Skip to content

Commit bba9577

Browse files
authored
Merge pull request #1903 from prafull01/force-webhook
✨ (go/v3) Add the --force option for the webhook
2 parents 762211a + e604838 commit bba9577

File tree

11 files changed

+66
-11
lines changed

11 files changed

+66
-11
lines changed

generate_testdata.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ scaffold_test_project() {
6363
$kb create api --group crew --version v1 --kind Admiral --controller=true --resource=true --namespaced=false --make=false
6464
$kb create webhook --group crew --version v1 --kind Admiral --defaulting
6565
$kb create api --group crew --version v1 --kind Laker --controller=true --resource=false --make=false
66+
if [ $project == "project-v3" ]; then
67+
$kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation --force
68+
fi
6669
elif [[ $project =~ multigroup ]]; then
6770
header_text 'Switching to multigroup layout ...'
6871
$kb edit --multigroup=true

pkg/cli/cli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ type CLI interface {
6767

6868
// cli defines the command line structure and interfaces that are used to
6969
// scaffold kubebuilder project files.
70-
type cli struct {
70+
type cli struct { //nolint:maligned
7171
/* Fields set by Option */
7272

7373
// Root command name. It is injected downstream to provide correct help, usage, examples and errors.

pkg/cli/edit.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package cli
17+
package cli // nolint:dupl
1818

1919
import (
2020
"fmt"
@@ -50,7 +50,6 @@ func (c cli) newEditContext() plugin.Context {
5050
}
5151
}
5252

53-
// nolint:dupl
5453
func (c cli) bindEdit(ctx plugin.Context, cmd *cobra.Command) {
5554
if len(c.resolvedPlugins) == 0 {
5655
cmdErr(cmd, fmt.Errorf(noPluginError))

pkg/model/config/config.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ func (c Config) HasGroup(group string) bool {
117117
return false
118118
}
119119

120+
// HasWebhook returns true if webhook is already present
121+
func (c Config) HasWebhook(resource ResourceData) bool {
122+
for _, r := range c.Resources {
123+
if r.isGVKEqualTo(resource) {
124+
return r.Webhooks != nil
125+
}
126+
}
127+
128+
return false
129+
}
130+
120131
// IsCRDVersionCompatible returns true if crdVersion can be added to the existing set of CRD versions.
121132
func (c Config) IsCRDVersionCompatible(crdVersion string) bool {
122133
return c.resourceAPIVersionCompatible("crd", crdVersion)

pkg/plugins/golang/v3/scaffolds/internal/templates/api/webhook.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ type Webhook struct { // nolint:maligned
4242
Defaulting bool
4343
// If scaffold the validating webhook
4444
Validating bool
45+
46+
Force bool
4547
}
4648

4749
// SetTemplateDefaults implements file.Template
@@ -69,7 +71,11 @@ func (f *Webhook) SetTemplateDefaults() error {
6971
}
7072
f.TemplateBody = webhookTemplate
7173

72-
f.IfExistsAction = file.Error
74+
if f.Force {
75+
f.IfExistsAction = file.Overwrite
76+
} else {
77+
f.IfExistsAction = file.Error
78+
}
7379

7480
f.GroupDomainWithDash = strings.Replace(f.Resource.Domain, ".", "-", -1)
7581

pkg/plugins/golang/v3/scaffolds/internal/templates/config/kdefault/webhook_manager_patch.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ var _ file.Template = &ManagerWebhookPatch{}
2727
// ManagerWebhookPatch scaffolds a file that defines the patch that enables webhooks on the manager
2828
type ManagerWebhookPatch struct {
2929
file.TemplateMixin
30+
31+
Force bool
3032
}
3133

3234
// SetTemplateDefaults implements file.Template
@@ -37,8 +39,12 @@ func (f *ManagerWebhookPatch) SetTemplateDefaults() error {
3739

3840
f.TemplateBody = managerWebhookPatchTemplate
3941

40-
// If file exists (ex. because a webhook was already created), skip creation.
41-
f.IfExistsAction = file.Skip
42+
if f.Force {
43+
f.IfExistsAction = file.Overwrite
44+
} else {
45+
// If file exists (ex. because a webhook was already created), skip creation.
46+
f.IfExistsAction = file.Skip
47+
}
4248

4349
return nil
4450
}

pkg/plugins/golang/v3/scaffolds/internal/templates/config/webhook/kustomization.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ type Kustomization struct {
3030

3131
// Version of webhook the project was configured with.
3232
WebhookVersion string
33+
34+
Force bool
3335
}
3436

3537
// SetTemplateDefaults implements file.Template
@@ -40,8 +42,12 @@ func (f *Kustomization) SetTemplateDefaults() error {
4042

4143
f.TemplateBody = kustomizeWebhookTemplate
4244

43-
// If file exists (ex. because a webhook was already created), skip creation.
44-
f.IfExistsAction = file.Skip
45+
if f.Force {
46+
f.IfExistsAction = file.Overwrite
47+
} else {
48+
// If file exists (ex. because a webhook was already created), skip creation.
49+
f.IfExistsAction = file.Skip
50+
}
4551

4652
if f.WebhookVersion == "" {
4753
f.WebhookVersion = "v1"

pkg/plugins/golang/v3/scaffolds/webhook.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ type webhookScaffolder struct {
3838
resource *resource.Resource
3939

4040
// Webhook type options.
41-
defaulting, validation, conversion bool
41+
defaulting, validation, conversion, force bool
4242
}
4343

4444
// NewWebhookScaffolder returns a new Scaffolder for v2 webhook creation operations
@@ -49,6 +49,7 @@ func NewWebhookScaffolder(
4949
defaulting bool,
5050
validation bool,
5151
conversion bool,
52+
force bool,
5253
) cmdutil.Scaffolder {
5354
return &webhookScaffolder{
5455
config: config,
@@ -57,6 +58,7 @@ func NewWebhookScaffolder(
5758
defaulting: defaulting,
5859
validation: validation,
5960
conversion: conversion,
61+
force: force,
6062
}
6163
}
6264

@@ -88,11 +90,12 @@ You need to implement the conversion.Hub and conversion.Convertible interfaces f
8890
WebhookVersion: s.resource.Webhooks.WebhookVersion,
8991
Defaulting: s.defaulting,
9092
Validating: s.validation,
93+
Force: s.force,
9194
},
9295
&templates.MainUpdater{WireWebhook: true},
9396
&kdefault.WebhookCAInjectionPatch{WebhookVersion: s.resource.Webhooks.WebhookVersion},
9497
&kdefault.ManagerWebhookPatch{},
95-
&webhook.Kustomization{WebhookVersion: s.resource.Webhooks.WebhookVersion},
98+
&webhook.Kustomization{WebhookVersion: s.resource.Webhooks.WebhookVersion, Force: s.force},
9699
&webhook.KustomizeConfig{},
97100
&webhook.Service{},
98101
); err != nil {

pkg/plugins/golang/v3/webhook.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package v3
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"io/ioutil"
2223
"path/filepath"
@@ -44,6 +45,9 @@ type createWebhookSubcommand struct {
4445
validation bool
4546
conversion bool
4647

48+
// force indicates that the resource should be created even if it already exists
49+
force bool
50+
4751
// runMake indicates whether to run make or not after scaffolding webhooks
4852
runMake bool
4953
}
@@ -79,6 +83,8 @@ func (p *createWebhookSubcommand) BindFlags(fs *pflag.FlagSet) {
7983
"version of {Mutating,Validating}WebhookConfigurations to scaffold. Options: [v1, v1beta1]")
8084

8185
fs.BoolVar(&p.runMake, "make", true, "if true, run make after generating files")
86+
fs.BoolVar(&p.force, "force", false,
87+
"attempt to create resource even if it already exists")
8288

8389
fs.BoolVar(&p.defaulting, "defaulting", false,
8490
"if set, scaffold the defaulting webhook")
@@ -112,6 +118,10 @@ func (p *createWebhookSubcommand) Validate() error {
112118
" kind and version provided", p.commandName)
113119
}
114120

121+
if p.config.HasWebhook(p.resource.Data()) && !p.force {
122+
return errors.New("webhook resource already exists")
123+
}
124+
115125
if !p.config.IsWebhookVersionCompatible(p.resource.Webhooks.WebhookVersion) {
116126
return fmt.Errorf("only one webhook version can be used for all resources, cannot add %q",
117127
p.resource.Webhooks.WebhookVersion)
@@ -129,7 +139,8 @@ func (p *createWebhookSubcommand) GetScaffolder() (cmdutil.Scaffolder, error) {
129139

130140
// Create the actual resource from the resource options
131141
res := p.resource.NewResource(p.config, false)
132-
return scaffolds.NewWebhookScaffolder(p.config, string(bp), res, p.defaulting, p.validation, p.conversion), nil
142+
return scaffolds.NewWebhookScaffolder(p.config, string(bp), res, p.defaulting, p.validation, p.conversion,
143+
p.force), nil
133144
}
134145

135146
func (p *createWebhookSubcommand) PostScaffold() error {

testdata/project-v3/api/v1/webhook_suite_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ var _ = BeforeSuite(func() {
8484
err = admissionv1beta1.AddToScheme(scheme)
8585
Expect(err).NotTo(HaveOccurred())
8686

87+
err = admissionv1beta1.AddToScheme(scheme)
88+
Expect(err).NotTo(HaveOccurred())
89+
8790
// +kubebuilder:scaffold:scheme
8891

8992
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
@@ -108,6 +111,9 @@ var _ = BeforeSuite(func() {
108111
err = (&Admiral{}).SetupWebhookWithManager(mgr)
109112
Expect(err).NotTo(HaveOccurred())
110113

114+
err = (&Captain{}).SetupWebhookWithManager(mgr)
115+
Expect(err).NotTo(HaveOccurred())
116+
111117
// +kubebuilder:scaffold:webhook
112118

113119
go func() {

0 commit comments

Comments
 (0)