Skip to content

Commit a9048aa

Browse files
committed
(manifests/v2) add support for webhooks by default, with minimal changes
Signed-off-by: Eric Stroczynski <ericstroczynski@gmail.com>
1 parent 640ddc7 commit a9048aa

File tree

18 files changed

+419
-93
lines changed

18 files changed

+419
-93
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
entries:
2+
- description: >
3+
(manifests/v2) Added a `config/manifests` kustomize patch to remove the cert-manager
4+
volume and volumeMount from manifests destined for `generate <bundle|packagemanifests>`
5+
kind: bugfix
6+
migration:
7+
header: (manifests/v2) Add a kustomize patch to remove the cert-manager volume/volumeMount from your CSV
8+
body: >
9+
OLM does [not yet support cert-manager](https://olm.operatorframework.io/docs/advanced-tasks/adding-admission-and-conversion-webhooks/#certificate-authority-requirements),
10+
so a JSON patch was added to remove this volume and mount such that
11+
OLM can itself create and manage certs for your Operator.
12+
13+
In `config/manifests/kustomization.yaml`, add the following:
14+
15+
```yaml
16+
patchesJson6902:
17+
- target:
18+
group: apps
19+
version: v1
20+
kind: Deployment
21+
name: controller-manager
22+
namespace: system
23+
patch: |-
24+
# Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs.
25+
# Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment.
26+
- op: remove
27+
path: /spec/template/spec/containers/1/volumeMounts/0
28+
# Remove the "cert" volume, since OLM will create and mount a set of certs.
29+
# Update the indices in this path if adding or removing volumes in the manager's Deployment.
30+
- op: remove
31+
path: /spec/template/spec/volumes/0
32+
```

hack/generate/samples/internal/go/v2/memcached_with_webhooks.go

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ func (mh *MemcachedGoWithWebhooks) Run() {
9090
pkg.CheckError("scaffolding webhook", err)
9191

9292
mh.implementingWebhooks()
93-
mh.uncommentKustomizationFile()
93+
mh.uncommentDefaultKustomization()
94+
mh.uncommentManifestsKustomization()
9495

9596
log.Infof("creating the bundle")
9697
err = mh.ctx.GenerateBundle()
@@ -106,35 +107,28 @@ func (mh *MemcachedGoWithWebhooks) Run() {
106107
pkg.CheckError("cleaning up", os.RemoveAll(filepath.Join(mh.ctx.Dir, "bin")))
107108
}
108109

109-
// uncommentKustomizationFile will uncomment the file kustomization.yaml
110-
func (mh *MemcachedGoWithWebhooks) uncommentKustomizationFile() {
111-
log.Infof("uncomment kustomization.yaml to enable webhook and ca injection")
112-
err := testutils.UncommentCode(
113-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
114-
"#- ../webhook", "#")
110+
// uncommentDefaultKustomization will uncomment code in config/default/kustomization.yaml
111+
func (mh *MemcachedGoWithWebhooks) uncommentDefaultKustomization() {
112+
var err error
113+
kustomization := filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml")
114+
log.Info("uncommenting config/default/kustomization.yaml to enable webhooks and ca injection")
115+
116+
err = testutils.UncommentCode(kustomization, "#- ../webhook", "#")
115117
pkg.CheckError("uncomment webhook", err)
116118

117-
err = testutils.UncommentCode(
118-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
119-
"#- ../certmanager", "#")
119+
err = testutils.UncommentCode(kustomization, "#- ../certmanager", "#")
120120
pkg.CheckError("uncomment certmanager", err)
121121

122-
err = testutils.UncommentCode(
123-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
124-
"#- ../prometheus", "#")
122+
err = testutils.UncommentCode(kustomization, "#- ../prometheus", "#")
125123
pkg.CheckError("uncomment prometheus", err)
126124

127-
err = testutils.UncommentCode(
128-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
129-
"#- manager_webhook_patch.yaml", "#")
125+
err = testutils.UncommentCode(kustomization, "#- manager_webhook_patch.yaml", "#")
130126
pkg.CheckError("uncomment manager_webhook_patch.yaml", err)
131127

132-
err = testutils.UncommentCode(
133-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
134-
"#- webhookcainjection_patch.yaml", "#")
128+
err = testutils.UncommentCode(kustomization, "#- webhookcainjection_patch.yaml", "#")
135129
pkg.CheckError("uncomment webhookcainjection_patch.yaml", err)
136130

137-
err = testutils.UncommentCode(filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
131+
err = testutils.UncommentCode(kustomization,
138132
`#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
139133
# objref:
140134
# kind: Certificate
@@ -164,6 +158,32 @@ func (mh *MemcachedGoWithWebhooks) uncommentKustomizationFile() {
164158
pkg.CheckError("uncommented certificate CR", err)
165159
}
166160

161+
// uncommentManifestsKustomization will uncomment code in config/manifests/kustomization.yaml
162+
func (mh *MemcachedGoWithWebhooks) uncommentManifestsKustomization() {
163+
var err error
164+
kustomization := filepath.Join(mh.ctx.Dir, "config", "manifests", "kustomization.yaml")
165+
log.Info("uncommenting config/manifests/kustomization.yaml to enable webhooks in OLM")
166+
167+
err = testutils.UncommentCode(kustomization,
168+
`#patchesJson6902:
169+
#- target:
170+
# group: apps
171+
# version: v1
172+
# kind: Deployment
173+
# name: controller-manager
174+
# namespace: system
175+
# patch: |-
176+
# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs.
177+
# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment.
178+
# - op: remove
179+
# path: /spec/template/spec/containers/1/volumeMounts/0
180+
# # Remove the "cert" volume, since OLM will create and mount a set of certs.
181+
# # Update the indices in this path if adding or removing volumes in the manager's Deployment.
182+
# - op: remove
183+
# path: /spec/template/spec/volumes/0`, "#")
184+
pkg.CheckError("uncommented webhook volume removal patch", err)
185+
}
186+
167187
// implementingWebhooks will customize the kind wekbhok file
168188
func (mh *MemcachedGoWithWebhooks) implementingWebhooks() {
169189
log.Infof("implementing webhooks")
@@ -327,7 +347,7 @@ const reconcileFragment = `// Fetch the Memcached instance
327347
return ctrl.Result{}, err
328348
}
329349
// Ask to requeue after 1 minute in order to give enough time for the
330-
// pods be created on the cluster side and the operand be able
350+
// pods be created on the cluster side and the operand be able
331351
// to do the next update step accurately.
332352
return ctrl.Result{RequeueAfter: time.Minute }, nil
333353
}

hack/generate/samples/internal/go/v3/memcached_with_webhooks.go

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ func (mh *MemcachedGoWithWebhooks) Run() {
9090
pkg.CheckError("scaffolding webhook", err)
9191

9292
mh.implementingWebhooks()
93-
mh.uncommentKustomizationFile()
93+
mh.uncommentDefaultKustomization()
94+
mh.uncommentManifestsKustomization()
9495

9596
log.Infof("creating the bundle")
9697
err = mh.ctx.GenerateBundle()
@@ -106,35 +107,28 @@ func (mh *MemcachedGoWithWebhooks) Run() {
106107
pkg.CheckError("cleaning up", os.RemoveAll(filepath.Join(mh.ctx.Dir, "bin")))
107108
}
108109

109-
// uncommentKustomizationFile will uncomment the file kustomization.yaml
110-
func (mh *MemcachedGoWithWebhooks) uncommentKustomizationFile() {
111-
log.Infof("uncomment kustomization.yaml to enable webhook and ca injection")
112-
err := testutils.UncommentCode(
113-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
114-
"#- ../webhook", "#")
110+
// uncommentDefaultKustomization will uncomment code in config/default/kustomization.yaml
111+
func (mh *MemcachedGoWithWebhooks) uncommentDefaultKustomization() {
112+
var err error
113+
kustomization := filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml")
114+
log.Info("uncommenting config/default/kustomization.yaml to enable webhooks and ca injection")
115+
116+
err = testutils.UncommentCode(kustomization, "#- ../webhook", "#")
115117
pkg.CheckError("uncomment webhook", err)
116118

117-
err = testutils.UncommentCode(
118-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
119-
"#- ../certmanager", "#")
119+
err = testutils.UncommentCode(kustomization, "#- ../certmanager", "#")
120120
pkg.CheckError("uncomment certmanager", err)
121121

122-
err = testutils.UncommentCode(
123-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
124-
"#- ../prometheus", "#")
122+
err = testutils.UncommentCode(kustomization, "#- ../prometheus", "#")
125123
pkg.CheckError("uncomment prometheus", err)
126124

127-
err = testutils.UncommentCode(
128-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
129-
"#- manager_webhook_patch.yaml", "#")
125+
err = testutils.UncommentCode(kustomization, "#- manager_webhook_patch.yaml", "#")
130126
pkg.CheckError("uncomment manager_webhook_patch.yaml", err)
131127

132-
err = testutils.UncommentCode(
133-
filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
134-
"#- webhookcainjection_patch.yaml", "#")
128+
err = testutils.UncommentCode(kustomization, "#- webhookcainjection_patch.yaml", "#")
135129
pkg.CheckError("uncomment webhookcainjection_patch.yaml", err)
136130

137-
err = testutils.UncommentCode(filepath.Join(mh.ctx.Dir, "config", "default", "kustomization.yaml"),
131+
err = testutils.UncommentCode(kustomization,
138132
`#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
139133
# objref:
140134
# kind: Certificate
@@ -164,6 +158,32 @@ func (mh *MemcachedGoWithWebhooks) uncommentKustomizationFile() {
164158
pkg.CheckError("uncommented certificate CR", err)
165159
}
166160

161+
// uncommentManifestsKustomization will uncomment code in config/manifests/kustomization.yaml
162+
func (mh *MemcachedGoWithWebhooks) uncommentManifestsKustomization() {
163+
var err error
164+
kustomization := filepath.Join(mh.ctx.Dir, "config", "manifests", "kustomization.yaml")
165+
log.Info("uncommenting config/manifests/kustomization.yaml to enable webhooks in OLM")
166+
167+
err = testutils.UncommentCode(kustomization,
168+
`#patchesJson6902:
169+
#- target:
170+
# group: apps
171+
# version: v1
172+
# kind: Deployment
173+
# name: controller-manager
174+
# namespace: system
175+
# patch: |-
176+
# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs.
177+
# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment.
178+
# - op: remove
179+
# path: /spec/template/spec/containers/1/volumeMounts/0
180+
# # Remove the "cert" volume, since OLM will create and mount a set of certs.
181+
# # Update the indices in this path if adding or removing volumes in the manager's Deployment.
182+
# - op: remove
183+
# path: /spec/template/spec/volumes/0`, "#")
184+
pkg.CheckError("uncommented webhook volume removal patch", err)
185+
}
186+
167187
// implementingWebhooks will customize the kind wekbhok file
168188
func (mh *MemcachedGoWithWebhooks) implementingWebhooks() {
169189
log.Infof("implementing webhooks")
@@ -321,7 +341,7 @@ const reconcileFragment = `// Fetch the Memcached instance
321341
return ctrl.Result{}, err
322342
}
323343
// Ask to requeue after 1 minute in order to give enough time for the
324-
// pods be created on the cluster side and the operand be able
344+
// pods be created on the cluster side and the operand be able
325345
// to do the next update step accurately.
326346
return ctrl.Result{RequeueAfter: time.Minute }, nil
327347
}

internal/cmd/operator-sdk/generate/kustomize/manifests.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,20 @@ import (
2222
"strings"
2323

2424
log "github.com/sirupsen/logrus"
25+
"github.com/spf13/afero"
2526
"github.com/spf13/cobra"
2627
"github.com/spf13/pflag"
2728
"k8s.io/apimachinery/pkg/runtime/schema"
2829
"k8s.io/apimachinery/pkg/util/validation"
2930
"sigs.k8s.io/kubebuilder/v3/pkg/config"
3031
cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2"
32+
"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
33+
"sigs.k8s.io/kubebuilder/v3/pkg/model/file"
3134
"sigs.k8s.io/yaml"
3235

3336
genutil "github.com/operator-framework/operator-sdk/internal/cmd/operator-sdk/generate/internal"
3437
"github.com/operator-framework/operator-sdk/internal/generate/clusterserviceversion/bases"
35-
"github.com/operator-framework/operator-sdk/internal/plugins/util/kustomize"
38+
manifestsv2 "github.com/operator-framework/operator-sdk/internal/plugins/manifests/v2"
3639
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
3740
"github.com/operator-framework/operator-sdk/internal/util/projutil"
3841
)
@@ -161,14 +164,6 @@ func (c *manifestsCmd) setDefaults(cfg config.Config) error {
161164
return nil
162165
}
163166

164-
// kustomization.yaml file contents for manifests. this should always be written to
165-
// config/manifests/kustomization.yaml since it only references files in config.
166-
const manifestsKustomization = `resources:
167-
- ../default
168-
- ../samples
169-
- ../scorecard
170-
`
171-
172167
// run generates kustomize bundle bases and a kustomization.yaml if one does not exist.
173168
func (c manifestsCmd) run(cfg config.Config) error {
174169

@@ -188,6 +183,7 @@ func (c manifestsCmd) run(cfg config.Config) error {
188183
}
189184
}
190185

186+
operatorType := projutil.PluginKeyToOperatorType(cfg.GetPluginChain())
191187
relBasePath := filepath.Join("bases", c.packageName+".clusterserviceversion.yaml")
192188
basePath := filepath.Join(c.inputDir, relBasePath)
193189
gvks, err := getGVKs(cfg)
@@ -196,7 +192,7 @@ func (c manifestsCmd) run(cfg config.Config) error {
196192
}
197193
base := bases.ClusterServiceVersion{
198194
OperatorName: c.packageName,
199-
OperatorType: projutil.PluginKeyToOperatorType(cfg.GetPluginChain()),
195+
OperatorType: operatorType,
200196
APIsDir: c.apisDir,
201197
Interactive: requiresInteraction(basePath, c.interactiveLevel),
202198
GVKs: gvks,
@@ -224,8 +220,13 @@ func (c manifestsCmd) run(cfg config.Config) error {
224220
}
225221

226222
// Write a kustomization.yaml to outputDir if one does not exist.
227-
if err := kustomize.WriteIfNotExist(c.outputDir, manifestsKustomization); err != nil {
228-
return fmt.Errorf("error writing kustomization.yaml: %v", err)
223+
kustomization := manifestsv2.Kustomization{SupportsWebhooks: operatorType == projutil.OperatorTypeGo}
224+
kustomization.IfExistsAction = file.Skip
225+
err = machinery.NewScaffold(machinery.Filesystem{FS: afero.NewOsFs()}, machinery.WithConfig(cfg)).Execute(
226+
&kustomization,
227+
)
228+
if err != nil {
229+
return fmt.Errorf("error scaffolding manifests: %v", err)
229230
}
230231

231232
if !c.quiet {

internal/plugins/ansible/v1/init.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func (p *initSubcommand) Run(fs machinery.Filesystem) error {
133133
}
134134

135135
// Run SDK phase 2 plugins.
136-
if err := p.runPhase2(); err != nil {
136+
if err := p.runPhase2(fs); err != nil {
137137
return err
138138
}
139139

@@ -149,8 +149,8 @@ func (p *initSubcommand) Run(fs machinery.Filesystem) error {
149149
}
150150

151151
// SDK phase 2 plugins.
152-
func (p *initSubcommand) runPhase2() error {
153-
if err := manifestsv2.RunInit(p.config); err != nil {
152+
func (p *initSubcommand) runPhase2(fs machinery.Filesystem) error {
153+
if err := manifestsv2.RunInit(p.config, fs); err != nil {
154154
return err
155155
}
156156
if err := scorecardv2.RunInit(p.config); err != nil {

internal/plugins/golang/v2/init.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,19 @@ func (p *initSubcommand) Run(fs machinery.Filesystem) error {
4747
}
4848

4949
// Run SDK phase 2 plugins.
50-
if err := p.runPhase2(); err != nil {
50+
if err := p.runPhase2(fs); err != nil {
5151
return err
5252
}
5353

5454
return nil
5555
}
5656

5757
// SDK phase 2 plugins.
58-
func (p *initSubcommand) runPhase2() error {
58+
func (p *initSubcommand) runPhase2(fs machinery.Filesystem) error {
5959
if err := envtest.RunInit(p.config); err != nil {
6060
return err
6161
}
62-
if err := manifestsv2.RunInit(p.config); err != nil {
62+
if err := manifestsv2.RunInit(p.config, fs); err != nil {
6363
return err
6464
}
6565
if err := scorecardv2.RunInit(p.config); err != nil {

internal/plugins/golang/v3/init.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ func (p *initSubcommand) Run(fs machinery.Filesystem) error {
4646
}
4747

4848
// Run SDK phase 2 plugins.
49-
if err := p.runPhase2(); err != nil {
49+
if err := p.runPhase2(fs); err != nil {
5050
return err
5151
}
5252

5353
return nil
5454
}
5555

5656
// SDK phase 2 plugins.
57-
func (p *initSubcommand) runPhase2() error {
58-
if err := manifestsv2.RunInit(p.config); err != nil {
57+
func (p *initSubcommand) runPhase2(fs machinery.Filesystem) error {
58+
if err := manifestsv2.RunInit(p.config, fs); err != nil {
5959
return err
6060
}
6161
if err := scorecardv2.RunInit(p.config); err != nil {

internal/plugins/helm/v1/init.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func (p *initSubcommand) Run(fs machinery.Filesystem) error {
161161
}
162162

163163
// Run SDK phase 2 plugins.
164-
if err := p.runPhase2(); err != nil {
164+
if err := p.runPhase2(fs); err != nil {
165165
return err
166166
}
167167

@@ -177,8 +177,8 @@ func (p *initSubcommand) Run(fs machinery.Filesystem) error {
177177
}
178178

179179
// SDK phase 2 plugins.
180-
func (p *initSubcommand) runPhase2() error {
181-
if err := manifestsv2.RunInit(p.config); err != nil {
180+
func (p *initSubcommand) runPhase2(fs machinery.Filesystem) error {
181+
if err := manifestsv2.RunInit(p.config, fs); err != nil {
182182
return err
183183
}
184184
if err := scorecardv2.RunInit(p.config); err != nil {

0 commit comments

Comments
 (0)