mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 18:02:01 +00:00
Merge pull request #91113 from soltysh/create_deployment
Refactor create deployment and add --port flag
This commit is contained in:
commit
7c3f7065db
@ -80,14 +80,14 @@ func NewCreateCronJobOptions(ioStreams genericclioptions.IOStreams) *CreateCronJ
|
|||||||
func NewCmdCreateCronJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
|
func NewCmdCreateCronJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
|
||||||
o := NewCreateCronJobOptions(ioStreams)
|
o := NewCreateCronJobOptions(ioStreams)
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "cronjob NAME --image=image --schedule='0/5 * * * ?' -- [COMMAND] [args...]",
|
Use: "cronjob NAME --image=image --schedule='0/5 * * * ?' -- [COMMAND] [args...]",
|
||||||
Aliases: []string{"cj"},
|
DisableFlagsInUseLine: false,
|
||||||
Short: cronjobLong,
|
Aliases: []string{"cj"},
|
||||||
Long: cronjobLong,
|
Short: cronjobLong,
|
||||||
Example: cronjobExample,
|
Long: cronjobLong,
|
||||||
|
Example: cronjobExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
|
||||||
cmdutil.CheckErr(o.Run())
|
cmdutil.CheckErr(o.Run())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -98,7 +98,9 @@ func NewCmdCreateCronJob(f cmdutil.Factory, ioStreams genericclioptions.IOStream
|
|||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
cmd.Flags().StringVar(&o.Image, "image", o.Image, "Image name to run.")
|
cmd.Flags().StringVar(&o.Image, "image", o.Image, "Image name to run.")
|
||||||
|
cmd.MarkFlagRequired("image")
|
||||||
cmd.Flags().StringVar(&o.Schedule, "schedule", o.Schedule, "A schedule in the Cron format the job should be run with.")
|
cmd.Flags().StringVar(&o.Schedule, "schedule", o.Schedule, "A schedule in the Cron format the job should be run with.")
|
||||||
|
cmd.MarkFlagRequired("schedule")
|
||||||
cmd.Flags().StringVar(&o.Restart, "restart", o.Restart, "job's restart policy. supported values: OnFailure, Never")
|
cmd.Flags().StringVar(&o.Restart, "restart", o.Restart, "job's restart policy. supported values: OnFailure, Never")
|
||||||
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-create")
|
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-create")
|
||||||
|
|
||||||
@ -158,20 +160,8 @@ func (o *CreateCronJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *CreateCronJobOptions) Validate() error {
|
|
||||||
if len(o.Image) == 0 {
|
|
||||||
return fmt.Errorf("--image must be specified")
|
|
||||||
}
|
|
||||||
if len(o.Schedule) == 0 {
|
|
||||||
return fmt.Errorf("--schedule must be specified")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *CreateCronJobOptions) Run() error {
|
func (o *CreateCronJobOptions) Run() error {
|
||||||
var cronjob *batchv1beta1.CronJob
|
cronjob := o.createCronJob()
|
||||||
cronjob = o.createCronJob()
|
|
||||||
|
|
||||||
if o.DryRunStrategy != cmdutil.DryRunClient {
|
if o.DryRunStrategy != cmdutil.DryRunClient {
|
||||||
createOptions := metav1.CreateOptions{}
|
createOptions := metav1.CreateOptions{}
|
||||||
if o.FieldManager != "" {
|
if o.FieldManager != "" {
|
||||||
|
@ -22,8 +22,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
v1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
utilrand "k8s.io/apimachinery/pkg/util/rand"
|
utilrand "k8s.io/apimachinery/pkg/util/rand"
|
||||||
@ -41,17 +42,26 @@ var (
|
|||||||
Create a deployment with the specified name.`))
|
Create a deployment with the specified name.`))
|
||||||
|
|
||||||
deploymentExample = templates.Examples(i18n.T(`
|
deploymentExample = templates.Examples(i18n.T(`
|
||||||
# Create a new deployment named my-dep that runs the busybox image.
|
# Create a deployment named my-dep that runs the busybox image.
|
||||||
kubectl create deployment my-dep --image=busybox`))
|
kubectl create deployment my-dep --image=busybox
|
||||||
|
|
||||||
|
# Create a deployment with command
|
||||||
|
kubectl create deployment my-dep --image=busybox -- date
|
||||||
|
|
||||||
|
# Create a deployment named my-dep that runs the busybox image and expose port 5701.
|
||||||
|
kubectl create deployment my-dep --image=busybox --port=5701`))
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeploymentOpts is returned by NewCmdCreateDeployment
|
// CreateDeploymentOptions is returned by NewCmdCreateDeployment
|
||||||
type DeploymentOpts struct {
|
type CreateDeploymentOptions struct {
|
||||||
PrintFlags *genericclioptions.PrintFlags
|
PrintFlags *genericclioptions.PrintFlags
|
||||||
PrintObj func(obj runtime.Object) error
|
|
||||||
|
PrintObj func(obj runtime.Object) error
|
||||||
|
|
||||||
Name string
|
Name string
|
||||||
Images []string
|
Images []string
|
||||||
|
Port int32
|
||||||
|
Command []string
|
||||||
Namespace string
|
Namespace string
|
||||||
EnforceNamespace bool
|
EnforceNamespace bool
|
||||||
FieldManager string
|
FieldManager string
|
||||||
@ -63,46 +73,55 @@ type DeploymentOpts struct {
|
|||||||
genericclioptions.IOStreams
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdCreateDeployment is a macro command to create a new deployment.
|
func NewCreateCreateDeploymentOptions(ioStreams genericclioptions.IOStreams) *CreateDeploymentOptions {
|
||||||
// This command is better known to users as `kubectl create deployment`.
|
return &CreateDeploymentOptions{
|
||||||
func NewCmdCreateDeployment(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
|
Port: -1,
|
||||||
options := &DeploymentOpts{
|
|
||||||
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
||||||
IOStreams: ioStreams,
|
IOStreams: ioStreams,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCmdCreateDeployment is a macro command to create a new deployment.
|
||||||
|
// This command is better known to users as `kubectl create deployment`.
|
||||||
|
func NewCmdCreateDeployment(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
|
||||||
|
o := NewCreateCreateDeploymentOptions(ioStreams)
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "deployment NAME --image=image [--dry-run=server|client|none]",
|
Use: "deployment NAME --image=image -- [COMMAND] [args...]",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Aliases: []string{"deploy"},
|
Aliases: []string{"deploy"},
|
||||||
Short: deploymentLong,
|
Short: deploymentLong,
|
||||||
Long: deploymentLong,
|
Long: deploymentLong,
|
||||||
Example: deploymentExample,
|
Example: deploymentExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(options.Run())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
cmdutil.CheckErr(o.Run())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
options.PrintFlags.AddFlags(cmd)
|
o.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmdutil.AddGeneratorFlags(cmd, "")
|
cmdutil.AddGeneratorFlags(cmd, "")
|
||||||
cmd.Flags().StringSliceVar(&options.Images, "image", []string{}, "Image name to run.")
|
cmd.Flags().StringSliceVar(&o.Images, "image", o.Images, "Image names to run.")
|
||||||
_ = cmd.MarkFlagRequired("image")
|
cmd.MarkFlagRequired("image")
|
||||||
cmdutil.AddFieldManagerFlagVar(cmd, &options.FieldManager, "kubectl-create")
|
cmd.Flags().Int32Var(&o.Port, "port", o.Port, "The port that this container exposes.")
|
||||||
|
cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-create")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete completes all the options
|
// Complete completes all the options
|
||||||
func (o *DeploymentOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
func (o *CreateDeploymentOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
name, err := NameFromCommandArgs(cmd, args)
|
name, err := NameFromCommandArgs(cmd, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.Name = name
|
o.Name = name
|
||||||
|
if len(args) > 1 {
|
||||||
|
o.Command = args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
clientConfig, err := f.ToRESTConfig()
|
clientConfig, err := f.ToRESTConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -144,8 +163,15 @@ func (o *DeploymentOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *CreateDeploymentOptions) Validate() error {
|
||||||
|
if len(o.Images) > 1 && len(o.Command) > 0 {
|
||||||
|
return fmt.Errorf("cannot specify multiple --image options and command")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Run performs the execution of 'create deployment' sub command
|
// Run performs the execution of 'create deployment' sub command
|
||||||
func (o *DeploymentOpts) Run() error {
|
func (o *CreateDeploymentOptions) Run() error {
|
||||||
deploy := o.createDeployment()
|
deploy := o.createDeployment()
|
||||||
|
|
||||||
if o.DryRunStrategy != cmdutil.DryRunClient {
|
if o.DryRunStrategy != cmdutil.DryRunClient {
|
||||||
@ -169,7 +195,7 @@ func (o *DeploymentOpts) Run() error {
|
|||||||
return o.PrintObj(deploy)
|
return o.PrintObj(deploy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *DeploymentOpts) createDeployment() *appsv1.Deployment {
|
func (o *CreateDeploymentOptions) createDeployment() *appsv1.Deployment {
|
||||||
one := int32(1)
|
one := int32(1)
|
||||||
labels := map[string]string{"app": o.Name}
|
labels := map[string]string{"app": o.Name}
|
||||||
selector := metav1.LabelSelector{MatchLabels: labels}
|
selector := metav1.LabelSelector{MatchLabels: labels}
|
||||||
@ -188,7 +214,7 @@ func (o *DeploymentOpts) createDeployment() *appsv1.Deployment {
|
|||||||
Spec: appsv1.DeploymentSpec{
|
Spec: appsv1.DeploymentSpec{
|
||||||
Replicas: &one,
|
Replicas: &one,
|
||||||
Selector: &selector,
|
Selector: &selector,
|
||||||
Template: v1.PodTemplateSpec{
|
Template: corev1.PodTemplateSpec{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
},
|
},
|
||||||
@ -200,8 +226,8 @@ func (o *DeploymentOpts) createDeployment() *appsv1.Deployment {
|
|||||||
|
|
||||||
// buildPodSpec parses the image strings and assemble them into the Containers
|
// buildPodSpec parses the image strings and assemble them into the Containers
|
||||||
// of a PodSpec. This is all you need to create the PodSpec for a deployment.
|
// of a PodSpec. This is all you need to create the PodSpec for a deployment.
|
||||||
func (o *DeploymentOpts) buildPodSpec() v1.PodSpec {
|
func (o *CreateDeploymentOptions) buildPodSpec() corev1.PodSpec {
|
||||||
podSpec := v1.PodSpec{Containers: []v1.Container{}}
|
podSpec := corev1.PodSpec{Containers: []corev1.Container{}}
|
||||||
for _, imageString := range o.Images {
|
for _, imageString := range o.Images {
|
||||||
// Retain just the image name
|
// Retain just the image name
|
||||||
imageSplit := strings.Split(imageString, "/")
|
imageSplit := strings.Split(imageString, "/")
|
||||||
@ -214,7 +240,11 @@ func (o *DeploymentOpts) buildPodSpec() v1.PodSpec {
|
|||||||
name = strings.Split(name, "@")[0]
|
name = strings.Split(name, "@")[0]
|
||||||
}
|
}
|
||||||
name = sanitizeAndUniquify(name)
|
name = sanitizeAndUniquify(name)
|
||||||
podSpec.Containers = append(podSpec.Containers, v1.Container{Name: name, Image: imageString})
|
podSpec.Containers = append(podSpec.Containers, corev1.Container{
|
||||||
|
Name: name,
|
||||||
|
Image: imageString,
|
||||||
|
Command: o.Command,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return podSpec
|
return podSpec
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ func TestCreateDeploymentNoImage(t *testing.T) {
|
|||||||
ioStreams := genericclioptions.NewTestIOStreamsDiscard()
|
ioStreams := genericclioptions.NewTestIOStreamsDiscard()
|
||||||
cmd := NewCmdCreateDeployment(tf, ioStreams)
|
cmd := NewCmdCreateDeployment(tf, ioStreams)
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
options := &DeploymentOpts{
|
options := &CreateDeploymentOptions{
|
||||||
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
|
||||||
DryRunStrategy: cmdutil.DryRunClient,
|
DryRunStrategy: cmdutil.DryRunClient,
|
||||||
IOStreams: ioStreams,
|
IOStreams: ioStreams,
|
||||||
|
@ -85,10 +85,11 @@ func NewCreateJobOptions(ioStreams genericclioptions.IOStreams) *CreateJobOption
|
|||||||
func NewCmdCreateJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
|
func NewCmdCreateJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
|
||||||
o := NewCreateJobOptions(ioStreams)
|
o := NewCreateJobOptions(ioStreams)
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "job NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]",
|
Use: "job NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...]",
|
||||||
Short: jobLong,
|
DisableFlagsInUseLine: true,
|
||||||
Long: jobLong,
|
Short: jobLong,
|
||||||
Example: jobExample,
|
Long: jobLong,
|
||||||
|
Example: jobExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -197,7 +197,7 @@ run_deployment_tests() {
|
|||||||
kubectl delete deployment test-nginx-extensions "${kube_flags[@]:?}"
|
kubectl delete deployment test-nginx-extensions "${kube_flags[@]:?}"
|
||||||
|
|
||||||
# Test kubectl create deployment
|
# Test kubectl create deployment
|
||||||
kubectl create deployment test-nginx-apps --image=k8s.gcr.io/nginx:test-cmd --generator=deployment-basic/apps.v1
|
kubectl create deployment test-nginx-apps --image=k8s.gcr.io/nginx:test-cmd
|
||||||
# Post-Condition: Deployment "nginx" is created.
|
# Post-Condition: Deployment "nginx" is created.
|
||||||
kube::test::get_object_assert 'deploy test-nginx-apps' "{{${container_name_field:?}}}" 'nginx'
|
kube::test::get_object_assert 'deploy test-nginx-apps' "{{${container_name_field:?}}}" 'nginx'
|
||||||
# and new generator was used, iow. new defaults are applied
|
# and new generator was used, iow. new defaults are applied
|
||||||
|
Loading…
Reference in New Issue
Block a user