1
16
17 package create
18
19 import (
20 "context"
21 "fmt"
22
23 "github.com/spf13/cobra"
24
25 batchv1 "k8s.io/api/batch/v1"
26 corev1 "k8s.io/api/core/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "k8s.io/apimachinery/pkg/runtime"
29 "k8s.io/cli-runtime/pkg/genericclioptions"
30 "k8s.io/cli-runtime/pkg/genericiooptions"
31 "k8s.io/cli-runtime/pkg/resource"
32 batchv1client "k8s.io/client-go/kubernetes/typed/batch/v1"
33 cmdutil "k8s.io/kubectl/pkg/cmd/util"
34 "k8s.io/kubectl/pkg/scheme"
35 "k8s.io/kubectl/pkg/util"
36 "k8s.io/kubectl/pkg/util/i18n"
37 "k8s.io/kubectl/pkg/util/templates"
38 )
39
40 var (
41 cronjobLong = templates.LongDesc(i18n.T(`
42 Create a cron job with the specified name.`))
43
44 cronjobExample = templates.Examples(`
45 # Create a cron job
46 kubectl create cronjob my-job --image=busybox --schedule="*/1 * * * *"
47
48 # Create a cron job with a command
49 kubectl create cronjob my-job --image=busybox --schedule="*/1 * * * *" -- date`)
50 )
51
52
53 type CreateCronJobOptions struct {
54 PrintFlags *genericclioptions.PrintFlags
55
56 PrintObj func(obj runtime.Object) error
57
58 Name string
59 Image string
60 Schedule string
61 Command []string
62 Restart string
63
64 Namespace string
65 EnforceNamespace bool
66 Client batchv1client.BatchV1Interface
67 DryRunStrategy cmdutil.DryRunStrategy
68 ValidationDirective string
69 Builder *resource.Builder
70 FieldManager string
71 CreateAnnotation bool
72
73 genericiooptions.IOStreams
74 }
75
76
77 func NewCreateCronJobOptions(ioStreams genericiooptions.IOStreams) *CreateCronJobOptions {
78 return &CreateCronJobOptions{
79 PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
80 IOStreams: ioStreams,
81 }
82 }
83
84
85 func NewCmdCreateCronJob(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *cobra.Command {
86 o := NewCreateCronJobOptions(ioStreams)
87 cmd := &cobra.Command{
88 Use: "cronjob NAME --image=image --schedule='0/5 * * * ?' -- [COMMAND] [args...]",
89 DisableFlagsInUseLine: false,
90 Aliases: []string{"cj"},
91 Short: i18n.T("Create a cron job with the specified name"),
92 Long: cronjobLong,
93 Example: cronjobExample,
94 Run: func(cmd *cobra.Command, args []string) {
95 cmdutil.CheckErr(o.Complete(f, cmd, args))
96 cmdutil.CheckErr(o.Run())
97 },
98 }
99
100 o.PrintFlags.AddFlags(cmd)
101
102 cmdutil.AddApplyAnnotationFlags(cmd)
103 cmdutil.AddValidateFlags(cmd)
104 cmdutil.AddDryRunFlag(cmd)
105 cmd.Flags().StringVar(&o.Image, "image", o.Image, "Image name to run.")
106 cmd.MarkFlagRequired("image")
107 cmd.Flags().StringVar(&o.Schedule, "schedule", o.Schedule, "A schedule in the Cron format the job should be run with.")
108 cmd.MarkFlagRequired("schedule")
109 cmd.Flags().StringVar(&o.Restart, "restart", o.Restart, "job's restart policy. supported values: OnFailure, Never")
110 cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-create")
111
112 return cmd
113 }
114
115
116 func (o *CreateCronJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
117 name, err := NameFromCommandArgs(cmd, args)
118 if err != nil {
119 return err
120 }
121 o.Name = name
122 if len(args) > 1 {
123 o.Command = args[1:]
124 }
125 if len(o.Restart) == 0 {
126 o.Restart = "OnFailure"
127 }
128
129 clientConfig, err := f.ToRESTConfig()
130 if err != nil {
131 return err
132 }
133 o.Client, err = batchv1client.NewForConfig(clientConfig)
134 if err != nil {
135 return err
136 }
137
138 o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
139 if err != nil {
140 return err
141 }
142 o.Builder = f.NewBuilder()
143
144 o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
145
146 o.DryRunStrategy, err = cmdutil.GetDryRunStrategy(cmd)
147 if err != nil {
148 return err
149 }
150 cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
151 printer, err := o.PrintFlags.ToPrinter()
152 if err != nil {
153 return err
154 }
155 o.PrintObj = func(obj runtime.Object) error {
156 return printer.PrintObj(obj, o.Out)
157 }
158
159 o.ValidationDirective, err = cmdutil.GetValidationDirective(cmd)
160 if err != nil {
161 return err
162 }
163
164 return nil
165 }
166
167
168 func (o *CreateCronJobOptions) Run() error {
169 cronJob := o.createCronJob()
170 if err := util.CreateOrUpdateAnnotation(o.CreateAnnotation, cronJob, scheme.DefaultJSONEncoder()); err != nil {
171 return err
172 }
173
174 if o.DryRunStrategy != cmdutil.DryRunClient {
175 createOptions := metav1.CreateOptions{}
176 if o.FieldManager != "" {
177 createOptions.FieldManager = o.FieldManager
178 }
179 createOptions.FieldValidation = o.ValidationDirective
180 if o.DryRunStrategy == cmdutil.DryRunServer {
181 createOptions.DryRun = []string{metav1.DryRunAll}
182 }
183 var err error
184 cronJob, err = o.Client.CronJobs(o.Namespace).Create(context.TODO(), cronJob, createOptions)
185 if err != nil {
186 return fmt.Errorf("failed to create cronjob: %v", err)
187 }
188 }
189
190 return o.PrintObj(cronJob)
191 }
192
193 func (o *CreateCronJobOptions) createCronJob() *batchv1.CronJob {
194 cronjob := &batchv1.CronJob{
195 TypeMeta: metav1.TypeMeta{APIVersion: batchv1.SchemeGroupVersion.String(), Kind: "CronJob"},
196 ObjectMeta: metav1.ObjectMeta{
197 Name: o.Name,
198 },
199 Spec: batchv1.CronJobSpec{
200 Schedule: o.Schedule,
201 JobTemplate: batchv1.JobTemplateSpec{
202 ObjectMeta: metav1.ObjectMeta{
203 Name: o.Name,
204 },
205 Spec: batchv1.JobSpec{
206 Template: corev1.PodTemplateSpec{
207 Spec: corev1.PodSpec{
208 Containers: []corev1.Container{
209 {
210 Name: o.Name,
211 Image: o.Image,
212 Command: o.Command,
213 },
214 },
215 RestartPolicy: corev1.RestartPolicy(o.Restart),
216 },
217 },
218 },
219 },
220 },
221 }
222 if o.EnforceNamespace {
223 cronjob.Namespace = o.Namespace
224 }
225 return cronjob
226 }
227
View as plain text