sigs.k8s.io/kubebuilder/v3@v3.14.0/hack/docs/internal/cronjob-tutorial/generate_cronjob.go (about)

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cronjob
    18  
    19  import (
    20  	"os"
    21  	"os/exec"
    22  	"path/filepath"
    23  
    24  	log "github.com/sirupsen/logrus"
    25  	"github.com/spf13/afero"
    26  
    27  	pluginutil "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
    28  	"sigs.k8s.io/kubebuilder/v3/test/e2e/utils"
    29  )
    30  
    31  type Sample struct {
    32  	ctx *utils.TestContext
    33  }
    34  
    35  func NewSample(binaryPath, samplePath string) Sample {
    36  	log.Infof("Generating the sample context of Cronjob...")
    37  
    38  	ctx := newSampleContext(binaryPath, samplePath, "GO111MODULE=on")
    39  
    40  	return Sample{&ctx}
    41  }
    42  
    43  func newSampleContext(binaryPath string, samplePath string, env ...string) utils.TestContext {
    44  	cmdContext := &utils.CmdContext{
    45  		Env: env,
    46  		Dir: samplePath,
    47  	}
    48  
    49  	testContext := utils.TestContext{
    50  		CmdContext: cmdContext,
    51  		BinaryName: binaryPath,
    52  	}
    53  
    54  	return testContext
    55  }
    56  
    57  // Prepare the Context for the sample project
    58  func (sp *Sample) Prepare() {
    59  	log.Infof("destroying directory for cronjob sample project")
    60  	sp.ctx.Destroy()
    61  
    62  	log.Infof("refreshing tools and creating directory...")
    63  	err := sp.ctx.Prepare()
    64  
    65  	CheckError("creating directory for sample project", err)
    66  }
    67  
    68  func (sp *Sample) GenerateSampleProject() {
    69  	log.Infof("Initializing the cronjob project")
    70  
    71  	err := sp.ctx.Init(
    72  		"--plugins", "go/v4",
    73  		"--domain", "tutorial.kubebuilder.io",
    74  		"--repo", "tutorial.kubebuilder.io/project",
    75  		"--license", "apache2",
    76  		"--owner", "The Kubernetes authors",
    77  	)
    78  	CheckError("Initializing the cronjob project", err)
    79  
    80  	log.Infof("Adding a new config type")
    81  	err = sp.ctx.CreateAPI(
    82  		"--group", "batch",
    83  		"--version", "v1",
    84  		"--kind", "CronJob",
    85  		"--resource", "--controller",
    86  	)
    87  	CheckError("Creating the API", err)
    88  
    89  	log.Infof("Implementing admission webhook")
    90  	err = sp.ctx.CreateWebhook(
    91  		"--group", "batch",
    92  		"--version", "v1",
    93  		"--kind", "CronJob",
    94  		"--defaulting", "--programmatic-validation",
    95  	)
    96  	CheckError("Implementing admission webhook", err)
    97  }
    98  
    99  func (sp *Sample) UpdateTutorial() {
   100  	log.Println("TODO: update tutorial")
   101  	// 1. update specs
   102  	updateSpec(sp)
   103  	// 2. update webhook
   104  	updateWebhook(sp)
   105  	// 3. generate extra files
   106  	codeGen(sp)
   107  	// 4. compensate other intro in API
   108  	updateAPIStuff(sp)
   109  	// 5. update reconciliation and main.go
   110  	// 5.1 update controller
   111  	updateController(sp)
   112  	// 5.2 update main.go
   113  	updateMain(sp)
   114  	// 6. generate extra files
   115  	codeGen(sp)
   116  	// 7. update suite_test explanation
   117  	updateSuiteTest(sp)
   118  	// 8. uncomment kustomization
   119  	updateKustomization(sp)
   120  	// 9. add example
   121  	updateExample(sp)
   122  	// 10. add test
   123  	addControllerTest(sp)
   124  }
   125  
   126  func codeGen(sp *Sample) {
   127  	cmd := exec.Command("go", "get", "github.com/robfig/cron")
   128  	_, err := sp.ctx.Run(cmd)
   129  	CheckError("Failed to get package robfig/cron", err)
   130  
   131  	cmd = exec.Command("make", "manifests")
   132  	_, err = sp.ctx.Run(cmd)
   133  	CheckError("Failed to run make manifests for cronjob tutorial", err)
   134  
   135  	cmd = exec.Command("make", "all")
   136  	_, err = sp.ctx.Run(cmd)
   137  	CheckError("Failed to run make all for cronjob tutorial", err)
   138  
   139  	cmd = exec.Command("go", "mod", "tidy")
   140  	_, err = sp.ctx.Run(cmd)
   141  	CheckError("Failed to run go mod tidy for cronjob tutorial", err)
   142  }
   143  
   144  // insert code to fix docs
   145  func updateSpec(sp *Sample) {
   146  	var err error
   147  	err = pluginutil.InsertCode(
   148  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   149  		`limitations under the License.
   150  */`,
   151  		`
   152  // +kubebuilder:docs-gen:collapse=Apache License
   153  
   154  /*
   155   */`)
   156  	CheckError("fixing cronjob_types.go", err)
   157  
   158  	err = pluginutil.InsertCode(
   159  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   160  		`package v1`,
   161  		`
   162  /*
   163   */`)
   164  	CheckError("fixing cronjob_types.go", err)
   165  
   166  	err = pluginutil.InsertCode(
   167  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   168  		`import (`,
   169  		`
   170  	batchv1 "k8s.io/api/batch/v1"
   171  	corev1 "k8s.io/api/core/v1"`)
   172  	CheckError("fixing cronjob_types.go", err)
   173  
   174  	err = pluginutil.InsertCode(
   175  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   176  		`to be serialized.`, CronjobSpecExplaination)
   177  	CheckError("fixing cronjob_types.go", err)
   178  
   179  	err = pluginutil.InsertCode(
   180  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   181  		`type CronJobSpec struct {`, CronjobSpecStruct)
   182  	CheckError("fixing cronjob_types.go", err)
   183  
   184  	err = pluginutil.ReplaceInFile(
   185  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   186  		`// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
   187  	// Important: Run "make" to regenerate code after modifying this file
   188  
   189  	// Foo is an example field of CronJob. Edit cronjob_types.go to remove/update
   190  	Foo string`+" `"+`json:"foo,omitempty"`+"`", "")
   191  	CheckError("fixing cronjob_types.go", err)
   192  
   193  	err = pluginutil.InsertCode(
   194  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   195  		`// Important: Run "make" to regenerate code after modifying this file`, CronjobList)
   196  	CheckError("fixing cronjob_types.go", err)
   197  
   198  	err = pluginutil.InsertCode(
   199  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   200  		`SchemeBuilder.Register(&CronJob{}, &CronJobList{})
   201  }`, `
   202  //+kubebuilder:docs-gen:collapse=Root Object Definitions`)
   203  	CheckError("fixing cronjob_types.go", err)
   204  
   205  	err = pluginutil.ReplaceInFile(
   206  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   207  		`// CronJob is the Schema for the cronjobs API
   208  type CronJob struct {`, `// CronJob is the Schema for the cronjobs API
   209  type CronJob struct {`+`
   210  	/*
   211  	 */`)
   212  	CheckError("fixing cronjob_types.go", err)
   213  
   214  	// fix lint
   215  	err = pluginutil.ReplaceInFile(
   216  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   217  		`
   218  	
   219  }`, "")
   220  	CheckError("fixing cronjob_types.go", err)
   221  
   222  	err = pluginutil.ReplaceInFile(
   223  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_types.go"),
   224  		`
   225  
   226  
   227  }`, "")
   228  	CheckError("fixing cronjob_types.go", err)
   229  }
   230  
   231  func updateAPIStuff(sp *Sample) {
   232  	var err error
   233  	// fix groupversion_info
   234  	err = pluginutil.InsertCode(
   235  		filepath.Join(sp.ctx.Dir, "api/v1/groupversion_info.go"),
   236  		`limitations under the License.
   237  */`, GroupversionIntro)
   238  	CheckError("fixing groupversion_info.go", err)
   239  
   240  	err = pluginutil.InsertCode(
   241  		filepath.Join(sp.ctx.Dir, "api/v1/groupversion_info.go"),
   242  		`	"sigs.k8s.io/controller-runtime/pkg/scheme"
   243  )`, GroupversionSchema)
   244  	CheckError("fixing groupversion_info.go", err)
   245  }
   246  
   247  func updateController(sp *Sample) {
   248  	var err error
   249  	err = pluginutil.InsertCode(
   250  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   251  		`limitations under the License.
   252  */`, ControllerIntro)
   253  	CheckError("fixing cronjob_controller.go", err)
   254  
   255  	err = pluginutil.ReplaceInFile(
   256  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   257  		`import (
   258  	"context"
   259  
   260  	"k8s.io/apimachinery/pkg/runtime"
   261  	ctrl "sigs.k8s.io/controller-runtime"
   262  	"sigs.k8s.io/controller-runtime/pkg/client"
   263  	"sigs.k8s.io/controller-runtime/pkg/log"
   264  
   265  	batchv1 "tutorial.kubebuilder.io/project/api/v1"
   266  )`, ControllerImport)
   267  	CheckError("fixing cronjob_controller.go", err)
   268  
   269  	err = pluginutil.InsertCode(
   270  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   271  		`Scheme *runtime.Scheme`, `
   272  	Clock`)
   273  	CheckError("fixing cronjob_controller.go", err)
   274  
   275  	err = pluginutil.InsertCode(
   276  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   277  		`	Clock
   278  }`, ControllerMockClock)
   279  	CheckError("fixing cronjob_controller.go", err)
   280  
   281  	err = pluginutil.InsertCode(
   282  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   283  		`//+kubebuilder:rbac:groups=batch.tutorial.kubebuilder.io,resources=cronjobs/finalizers,verbs=update`, ControllerReconcile)
   284  	CheckError("fixing cronjob_controller.go", err)
   285  
   286  	err = pluginutil.ReplaceInFile(
   287  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   288  		`	_ = log.FromContext(ctx)
   289  
   290  	// TODO(user): your logic here
   291  
   292  	return ctrl.Result{}, nil
   293  }`, ControllerReconcileLogic)
   294  	CheckError("fixing cronjob_controller.go", err)
   295  
   296  	err = pluginutil.InsertCode(
   297  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   298  		`SetupWithManager(mgr ctrl.Manager) error {`, ControllerSetupWithManager)
   299  	CheckError("fixing cronjob_controller.go", err)
   300  
   301  	err = pluginutil.InsertCode(
   302  		filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller.go"),
   303  		`For(&batchv1.CronJob{}).`, `
   304  		Owns(&kbatch.Job{}).`)
   305  	CheckError("fixing cronjob_controller.go", err)
   306  }
   307  
   308  func updateMain(sp *Sample) {
   309  	var err error
   310  	err = pluginutil.InsertCode(
   311  		filepath.Join(sp.ctx.Dir, "cmd/main.go"),
   312  		`limitations under the License.
   313  */`,
   314  		`
   315  // +kubebuilder:docs-gen:collapse=Apache License`)
   316  	CheckError("fixing main.go", err)
   317  
   318  	err = pluginutil.InsertCode(
   319  		filepath.Join(sp.ctx.Dir, "cmd/main.go"),
   320  		`//+kubebuilder:scaffold:imports
   321  )`, MainBatch)
   322  	CheckError("fixing main.go", err)
   323  
   324  	err = pluginutil.InsertCode(
   325  		filepath.Join(sp.ctx.Dir, "cmd/main.go"),
   326  		`//+kubebuilder:scaffold:scheme
   327  }`, `
   328  /*
   329  The other thing that's changed is that kubebuilder has added a block calling our
   330  CronJob controller's`+" `"+`SetupWithManager`+"`"+` method.
   331  */`)
   332  	CheckError("fixing main.go", err)
   333  
   334  	err = pluginutil.InsertCode(
   335  		filepath.Join(sp.ctx.Dir, "cmd/main.go"),
   336  		`func main() {`, `
   337  	/*
   338  	 */`)
   339  	CheckError("fixing main.go", err)
   340  
   341  	err = pluginutil.InsertCode(
   342  		filepath.Join(sp.ctx.Dir, "cmd/main.go"),
   343  		`if err != nil {
   344  		setupLog.Error(err, "unable to start manager")
   345  		os.Exit(1)
   346  	}`, `
   347  
   348  	// +kubebuilder:docs-gen:collapse=old stuff`)
   349  	CheckError("fixing main.go", err)
   350  
   351  	err = pluginutil.InsertCode(
   352  		filepath.Join(sp.ctx.Dir, "cmd/main.go"),
   353  		`setupLog.Error(err, "unable to create controller", "controller", "CronJob")
   354  		os.Exit(1)
   355  	}`, MainEnableWebhook)
   356  	CheckError("fixing main.go", err)
   357  
   358  	err = pluginutil.InsertCode(
   359  		filepath.Join(sp.ctx.Dir, "cmd/main.go"),
   360  		`setupLog.Error(err, "problem running manager")
   361  		os.Exit(1)
   362  	}`, `
   363  	// +kubebuilder:docs-gen:collapse=old stuff`)
   364  	CheckError("fixing main.go", err)
   365  }
   366  
   367  func updateWebhook(sp *Sample) {
   368  	var err error
   369  	err = pluginutil.InsertCode(
   370  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   371  		`limitations under the License.
   372  */`,
   373  		`
   374  // +kubebuilder:docs-gen:collapse=Apache License`)
   375  	CheckError("fixing cronjob_webhook.go by adding collapse", err)
   376  
   377  	err = pluginutil.ReplaceInFile(
   378  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   379  		`import (
   380  	"k8s.io/apimachinery/pkg/runtime"
   381  	ctrl "sigs.k8s.io/controller-runtime"
   382  	logf "sigs.k8s.io/controller-runtime/pkg/log"
   383  	"sigs.k8s.io/controller-runtime/pkg/webhook"
   384  	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
   385  )
   386  
   387  // log is for logging in this package.
   388  `, WebhookIntro)
   389  	CheckError("fixing cronjob_webhook.go", err)
   390  
   391  	err = pluginutil.InsertCode(
   392  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   393  		`var cronjoblog = logf.Log.WithName("cronjob-resource")`,
   394  		`
   395  /*
   396  Then, we set up the webhook with the manager.
   397  */`)
   398  	CheckError("fixing cronjob_webhook.go by setting webhook with manager comment", err)
   399  
   400  	err = pluginutil.ReplaceInFile(
   401  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   402  		`// TODO(user): EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!`, WebhookMarker)
   403  	CheckError("fixing cronjob_webhook.go by replacing TODO", err)
   404  
   405  	err = pluginutil.ReplaceInFile(
   406  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   407  		`// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.`, "")
   408  	CheckError("fixing cronjob_webhook.go by replace TODO to change verbs", err)
   409  
   410  	err = pluginutil.ReplaceInFile(
   411  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   412  		`//+kubebuilder:webhook:path=/mutate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,sideEffects=None,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v1,name=mcronjob.kb.io,admissionReviewVersions=v1`, "")
   413  	CheckError("fixing cronjob_webhook.go by replacing marker", err)
   414  
   415  	err = pluginutil.ReplaceInFile(
   416  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   417  		`//+kubebuilder:webhook:path=/validate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,sideEffects=None,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v1,name=vcronjob.kb.io,admissionReviewVersions=v1`, "")
   418  	CheckError("fixing cronjob_webhook.go validate batch marker", err)
   419  
   420  	err = pluginutil.ReplaceInFile(
   421  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   422  		`cronjoblog.Info("default", "name", r.Name)
   423  
   424  	// TODO(user): fill in your defaulting logic.
   425  `, WebhookValidate)
   426  	CheckError("fixing cronjob_webhook.go by adding logic", err)
   427  
   428  	err = pluginutil.ReplaceInFile(
   429  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   430  		`// TODO(user): fill in your validation logic upon object creation.
   431  	return nil, nil`,
   432  		`
   433  	return nil, r.validateCronJob()`)
   434  	CheckError("fixing cronjob_webhook.go by fill in your validation", err)
   435  
   436  	err = pluginutil.ReplaceInFile(
   437  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   438  		`// TODO(user): fill in your validation logic upon object update.
   439  	return nil, nil`,
   440  		`
   441  	return nil, r.validateCronJob()`)
   442  	CheckError("fixing cronjob_webhook.go by adding validation logic upon object update", err)
   443  
   444  	err = pluginutil.InsertCode(
   445  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   446  		`func (r *CronJob) ValidateDelete() (admission.Warnings, error) {
   447  	cronjoblog.Info("validate delete", "name", r.Name)
   448  
   449  	// TODO(user): fill in your validation logic upon object deletion.
   450  	return nil, nil
   451  }`, WebhookValidateSpec)
   452  	CheckError("fixing cronjob_webhook.go", err)
   453  
   454  	err = pluginutil.ReplaceInFile(
   455  		filepath.Join(sp.ctx.Dir, "api/v1/cronjob_webhook.go"),
   456  		`validate anything on deletion.
   457  */
   458  }`, `validate anything on deletion.
   459  */`)
   460  	CheckError("fixing cronjob_webhook.go by adding comments to validate on deletion", err)
   461  }
   462  
   463  func updateSuiteTest(sp *Sample) {
   464  	var err error
   465  	err = pluginutil.InsertCode(
   466  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   467  		`limitations under the License.
   468  */`, SuiteTestIntro)
   469  	CheckError("updating suite_test.go to add license intro", err)
   470  
   471  	err = pluginutil.InsertCode(
   472  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   473  		`import (`, `
   474  	"context"`)
   475  	CheckError("updating suite_test.go to add context", err)
   476  
   477  	err = pluginutil.InsertCode(
   478  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   479  		`
   480  	"testing"
   481  `, `
   482  	ctrl "sigs.k8s.io/controller-runtime"
   483  `)
   484  	CheckError("updating suite_test.go to add ctrl import", err)
   485  
   486  	err = pluginutil.ReplaceInFile(
   487  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   488  		`
   489  var cfg *rest.Config
   490  var k8sClient client.Client
   491  var testEnv *envtest.Environment
   492  `, SuiteTestEnv)
   493  	CheckError("updating suite_test.go to add more variables", err)
   494  
   495  	err = pluginutil.InsertCode(
   496  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   497  		`
   498  	logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
   499  `, SuiteTestReadCRD)
   500  	CheckError("updating suite_test.go to add text about CRD", err)
   501  
   502  	err = pluginutil.InsertCode(
   503  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   504  		`, runtime.GOOS, runtime.GOARCH)),
   505  	}
   506  `, `
   507  	/*
   508  		Then, we start the envtest cluster.
   509  	*/`)
   510  	CheckError("updating suite_test.go to add text to show where envtest cluster start", err)
   511  
   512  	err = pluginutil.ReplaceInFile(
   513  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   514  		`
   515  	err = batchv1.AddToScheme(scheme.Scheme)
   516  	Expect(err).NotTo(HaveOccurred())
   517  
   518  	//+kubebuilder:scaffold:scheme
   519  `, SuiteTestAddSchema)
   520  	CheckError("updating suite_test.go to add schema", err)
   521  
   522  	err = pluginutil.InsertCode(
   523  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   524  		`
   525  	k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
   526  	Expect(err).NotTo(HaveOccurred())
   527  	Expect(k8sClient).NotTo(BeNil())
   528  `, SuiteTestDescription)
   529  	CheckError("updating suite_test.go for test description", err)
   530  
   531  	err = pluginutil.ReplaceInFile(
   532  		filepath.Join(sp.ctx.Dir, "internal/controller/suite_test.go"),
   533  		`
   534  var _ = AfterSuite(func() {
   535  	By("tearing down the test environment")
   536  	err := testEnv.Stop()
   537  	Expect(err).NotTo(HaveOccurred())
   538  })
   539  `, SuiteTestCleanup)
   540  	CheckError("updating suite_test.go to cleanup tests", err)
   541  }
   542  
   543  func updateKustomization(sp *Sample) {
   544  	var err error
   545  	err = pluginutil.UncommentCode(
   546  		filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
   547  		`#- ../certmanager`, `#`)
   548  	CheckError("fixing default/kustomization", err)
   549  
   550  	err = pluginutil.UncommentCode(
   551  		filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
   552  		`#- path: webhookcainjection`, `#`)
   553  	CheckError("fixing default/kustomization", err)
   554  
   555  	err = pluginutil.UncommentCode(
   556  		filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
   557  		`#- ../prometheus`, `#`)
   558  	CheckError("fixing default/kustomization", err)
   559  
   560  	err = pluginutil.UncommentCode(
   561  		filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
   562  		DefaultKustomization, `#`)
   563  	CheckError("fixing default/kustomization", err)
   564  
   565  	err = pluginutil.UncommentCode(
   566  		filepath.Join(sp.ctx.Dir, "config/crd/kustomization.yaml"),
   567  		`#- path: patches/cainjection_in_cronjobs.yaml`, `#`)
   568  	CheckError("fixing crd/kustomization", err)
   569  }
   570  
   571  func updateExample(sp *Sample) {
   572  	var err error
   573  
   574  	// samples/batch_v1_cronjob
   575  	err = pluginutil.InsertCode(
   576  		filepath.Join(sp.ctx.Dir, "config/samples/batch_v1_cronjob.yaml"),
   577  		`spec:`, CronjobSample)
   578  	CheckError("fixing samples/batch_v1_cronjob.yaml", err)
   579  
   580  	err = pluginutil.ReplaceInFile(
   581  		filepath.Join(sp.ctx.Dir, "config/samples/batch_v1_cronjob.yaml"),
   582  		`# TODO(user): Add fields here`, "")
   583  	CheckError("fixing samples/batch_v1_cronjob.yaml", err)
   584  
   585  	// update default/manager_auth_proxy_patch.yaml
   586  	err = pluginutil.InsertCode(
   587  		filepath.Join(sp.ctx.Dir, "config/default/manager_auth_proxy_patch.yaml"),
   588  		` template:
   589      spec:`, ManagerAuthProxySample)
   590  	CheckError("fixing default/manager_auth_proxy_patch.yaml", err)
   591  }
   592  
   593  func addControllerTest(sp *Sample) {
   594  	var fs = afero.NewOsFs()
   595  	err := afero.WriteFile(fs, filepath.Join(sp.ctx.Dir, "internal/controller/cronjob_controller_test.go"), []byte(ControllerTest), 0600)
   596  	CheckError("adding cronjob_controller_test", err)
   597  }
   598  
   599  // CheckError will exit with exit code 1 when err is not nil.
   600  func CheckError(msg string, err error) {
   601  	if err != nil {
   602  		log.Errorf("error %s: %s", msg, err)
   603  		os.Exit(1)
   604  	}
   605  }