Skip to content

Commit

Permalink
(kustomize/v2, go/v4): Fix ca injection for conversion webhooks
Browse files Browse the repository at this point in the history
The CA injection patch has **not** worked for `go/v4` and `kustomize/v2` (release `3.5.0`) due to the need to replace `vars` with `replacements`, as `vars` are no longer supported in the latest major versions of Kustomize.

However, since webhook `--conversion` was an incomplete feature until the upcoming Kubebuilder future release `v4.4.0` (where [PR kubernetes-sigs#4254](kubernetes-sigs#4254) is expected to be merged), users likely didn’t encounter this issue or addressed it manually by fixing the scaffold.

**Note:** This change only affects projects that require a **conversion webhook**.
  • Loading branch information
camilamacedo86 committed Nov 6, 2024
1 parent 5ce0387 commit eb167ea
Show file tree
Hide file tree
Showing 48 changed files with 1,268 additions and 219 deletions.
17 changes: 12 additions & 5 deletions .github/workflows/test-e2e-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ jobs:
run: |
KUSTOMIZATION_FILE_PATH="testdata/project-v4/config/default/kustomization.yaml"
sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '50,177s/^#//' $KUSTOMIZATION_FILE_PATH
# Uncomment all cert-manager injections
sed -i '50,172s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '174,198s/^#//' $KUSTOMIZATION_FILE_PATH
cd testdata/project-v4/
go mod tidy
Expand Down Expand Up @@ -81,9 +83,12 @@ jobs:
KUSTOMIZATION_FILE_PATH="testdata/project-v4-with-plugins/config/default/kustomization.yaml"
sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH
# Uncomment only ValidatingWebhookConfiguration
# from cert-manager replaces
sed -i '50,116s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '148,177s/^#//' $KUSTOMIZATION_FILE_PATH
# from cert-manager replaces; we are leaving defaulting uncommented
# since this sample has no defaulting webhooks
sed -i '50,155s/^#//' $KUSTOMIZATION_FILE_PATH
# Uncomment only --conversion webhooks CA injection
sed -i '144,163s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '165,180s/^#//' $KUSTOMIZATION_FILE_PATH
cd testdata/project-v4-with-plugins/
go mod tidy
Expand Down Expand Up @@ -122,7 +127,9 @@ jobs:
run: |
KUSTOMIZATION_FILE_PATH="testdata/project-v4-multigroup/config/default/kustomization.yaml"
sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '50,177s/^#//' $KUSTOMIZATION_FILE_PATH
# Uncomment all cert-manager injections
sed -i '50,163s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '165,180s/^#//' $KUSTOMIZATION_FILE_PATH
cd testdata/project-v4-multigroup
go mod tidy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ patches:
# patches here are for enabling the conversion webhook for each CRD
# +kubebuilder:scaffold:crdkustomizewebhookpatch

# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
# +kubebuilder:scaffold:crdkustomizecainjectionpatch

# [WEBHOOK] To enable webhook, uncomment the following section
# the following config is for teaching kustomize how to do kustomization for CRDs.
#configurations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,27 +151,13 @@ replacements:
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.namespace # Namespace of the certificate CR
# targets:
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# create: true
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectionns
# - source:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.name
# targets:
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# create: true
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectionname
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ patches:
# patches here are for enabling the conversion webhook for each CRD
# +kubebuilder:scaffold:crdkustomizewebhookpatch

# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
# +kubebuilder:scaffold:crdkustomizecainjectionpatch

# [WEBHOOK] To enable webhook, uncomment the following section
# the following config is for teaching kustomize how to do kustomization for CRDs.
#configurations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,27 +151,13 @@ patches:
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.namespace # Namespace of the certificate CR
# targets:
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# create: true
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectionns
# - source:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.name
# targets:
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# create: true
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectionname
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ patches:
- path: patches/webhook_in_cronjobs.yaml
# +kubebuilder:scaffold:crdkustomizewebhookpatch

# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- path: patches/cainjection_in_cronjobs.yaml
# +kubebuilder:scaffold:crdkustomizecainjectionpatch

# [WEBHOOK] To enable webhook, uncomment the following section
# the following config is for teaching kustomize how to do kustomization for CRDs.
configurations:
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -151,27 +151,31 @@ replacements:
version: v1
name: serving-cert # This name should match the one in certificate.yaml
fieldPath: .metadata.namespace # Namespace of the certificate CR
targets:
targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
- select:
kind: CustomResourceDefinition
name: cronjobs.batch.tutorial.kubebuilder.io
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 0
create: true
# +kubebuilder:scaffold:crdkustomizecainjectionns
- source:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert # This name should match the one in certificate.yaml
fieldPath: .metadata.name
targets:
targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
- select:
kind: CustomResourceDefinition
name: cronjobs.batch.tutorial.kubebuilder.io
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 1
create: true
# +kubebuilder:scaffold:crdkustomizecainjectionname
59 changes: 58 additions & 1 deletion docs/book/src/reference/markers/scaffold.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,67 @@ properly registered with the manager, so that the controller can reconcile the r
| `+kubebuilder:scaffold:webhook` | `webhooks suite tests` files | Marks where webhook setup functions are added. |
| `+kubebuilder:scaffold:crdkustomizeresource`| `config/crd` | Marks where CRD custom resource patches are added. |
| `+kubebuilder:scaffold:crdkustomizewebhookpatch` | `config/crd` | Marks where CRD webhook patches are added. |
| `+kubebuilder:scaffold:crdkustomizecainjectionpatch` | `config/crd` | Marks where CA injection patches are added for the webhook. |
| `+kubebuilder:scaffold:crdkustomizecainjectionns` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. |
| `+kubebuilder:scaffold:crdkustomizecainjectioname` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. |
| **(No longer supported)** `+kubebuilder:scaffold:crdkustomizecainjectionpatch` | `config/crd` | Marks where CA injection patches are added for the webhooks. Replaced by `+kubebuilder:scaffold:crdkustomizecainjectionns` and `+kubebuilder:scaffold:crdkustomizecainjectioname` |
| `+kubebuilder:scaffold:manifestskustomizesamples` | `config/samples` | Marks where Kustomize sample manifests are injected. |
| `+kubebuilder:scaffold:e2e-webhooks-checks` | `test/e2e` | Adds e2e checks for webhooks depending on the types of webhooks scaffolded. |

<aside class="note warning">
<h1> **(No longer supported)** `+kubebuilder:scaffold:crdkustomizecainjectionpatch` </h1>

If you find this marker in your code please:

1. **Remove the CERTMANAGER Section from `config/crd/kustomization.yaml`:**

Delete the `CERTMANAGER` section to prevent unintended CA injection patches for CRDs. Ensure the following lines are removed or commented out:

```yaml
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- path: patches/cainjection_in_firstmates.yaml
# +kubebuilder:scaffold:crdkustomizecainjectionpatch
```

2. **Ensure CA Injection Configuration in `config/default/kustomization.yaml`:**

Under the `[CERTMANAGER]` replacement in `config/default/kustomization.yaml`, add the following code for proper CA injection generation:

**NOTE:** You must ensure that the code contains the following target markers:
- `+kubebuilder:scaffold:crdkustomizecainjectionns`
- `+kubebuilder:scaffold:crdkustomizecainjectioname`

```yaml
# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion)
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.namespace # Namespace of the certificate CR
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectionns
# - source:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.name
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectioname
```

3. **Ensure Only Conversion Webhook Patches in `config/crd/patches`:**

The `config/crd/patches` directory and the corresponding entries in `config/crd/kustomization.yaml` should only contain files for conversion webhooks. Previously, a bug caused the patch file to be generated for any webhook, but only patches for webhooks scaffolded with the `--conversion` option should be included.

For further guidance, you can refer to examples in the `testdata/` directory in the Kubebuilder repository.

> **Alternatively**: You can use the [`alpha generate`](./../rescaffold.md) command to re-generate the project from scratch
> using the latest release available. Afterward, you can re-add only your code implementation on top to ensure your project
> includes all the latest bug fixes and enhancements.

</aside>

<aside class="note">
<h1>Creating Your Own Markers</h1>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ func (sp *Sample) updateDefaultKustomize() {
// Enable CA for Conversion Webhook
err := pluginutil.UncommentCode(
filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
caConversionCRDDefaultKustomize, `#`)
caInjectionNamespace, `#`)
hackutils.CheckError("fixing default/kustomization", err)

// Enable CA for Conversion Webhook
err = pluginutil.UncommentCode(
filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
caInjectionCert, `#`)
hackutils.CheckError("fixing default/kustomization", err)
}

Expand Down
13 changes: 8 additions & 5 deletions hack/docs/internal/multiversion-tutorial/kustomize.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,34 @@ limitations under the License.

package multiversion

const caConversionCRDDefaultKustomize = `#
const caInjectionNamespace = `#
# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion)
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.namespace # Namespace of the certificate CR
# targets:
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# - select:
# kind: CustomResourceDefinition
# name: cronjobs.batch.tutorial.kubebuilder.io
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# create: true
# - source:
# create: true`

const caInjectionCert = `# - source:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # This name should match the one in certificate.yaml
# fieldPath: .metadata.name
# targets:
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# - select:
# kind: CustomResourceDefinition
# name: cronjobs.batch.tutorial.kubebuilder.io
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
Expand Down
1 change: 1 addition & 0 deletions pkg/plugins/common/kustomize/v2/scaffolds/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func (s *apiScaffolder) Scaffold() error {
}
}

// nolint:goconst
kustomizeFilePath := "config/default/kustomization.yaml"
err := pluginutil.UncommentCode(kustomizeFilePath, "#- ../crd", `#`)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,40 +45,35 @@ func (f *Kustomization) SetTemplateDefaults() error {
f.TemplateBody = fmt.Sprintf(kustomizationTemplate,
machinery.NewMarkerFor(f.Path, resourceMarker),
machinery.NewMarkerFor(f.Path, webhookPatchMarker),
machinery.NewMarkerFor(f.Path, caInjectionPatchMarker),
)

return nil
}

//nolint:gosec to ignore false complain G101: Potential hardcoded credentials (gosec)
const (
resourceMarker = "crdkustomizeresource"
webhookPatchMarker = "crdkustomizewebhookpatch"
caInjectionPatchMarker = "crdkustomizecainjectionpatch"
resourceMarker = "crdkustomizeresource"
webhookPatchMarker = "crdkustomizewebhookpatch"
)

// GetMarkers implements file.Inserter
func (f *Kustomization) GetMarkers() []machinery.Marker {
return []machinery.Marker{
machinery.NewMarkerFor(f.Path, resourceMarker),
machinery.NewMarkerFor(f.Path, webhookPatchMarker),
machinery.NewMarkerFor(f.Path, caInjectionPatchMarker),
}
}

const (
resourceCodeFragment = `- bases/%s_%s.yaml
`
webhookPatchCodeFragment = `- path: patches/webhook_in_%s.yaml
`
caInjectionPatchCodeFragment = `#- path: patches/cainjection_in_%s.yaml
`
)

// GetCodeFragments implements file.Inserter
func (f *Kustomization) GetCodeFragments() machinery.CodeFragmentsMap {
fragments := make(machinery.CodeFragmentsMap, 3)
fragments := make(machinery.CodeFragmentsMap, 2)

// Generate resource code fragments
res := make([]string, 0)
Expand All @@ -98,21 +93,11 @@ func (f *Kustomization) GetCodeFragments() machinery.CodeFragmentsMap {
}
}

// Generate resource code fragments
caInjectionPatch := make([]string, 0)
if !f.Resource.Webhooks.IsEmpty() && f.Resource.Webhooks.Conversion {
caInjectionPatch = append(caInjectionPatch, fmt.Sprintf(caInjectionPatchCodeFragment, suffix))
}

// Only store code fragments in the map if the slices are non-empty
if len(res) != 0 {
fragments[machinery.NewMarkerFor(f.Path, resourceMarker)] = res
}

if len(caInjectionPatch) != 0 {
fragments[machinery.NewMarkerFor(f.Path, caInjectionPatchMarker)] = caInjectionPatch
}

return fragments
}

Expand All @@ -127,10 +112,6 @@ patches:
# patches here are for enabling the conversion webhook for each CRD
%s
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
%s
# [WEBHOOK] To enable webhook, uncomment the following section
# the following config is for teaching kustomize how to do kustomization for CRDs.
#configurations:
Expand Down
Loading

0 comments on commit eb167ea

Please sign in to comment.