Skip to content

feat: allow recreating a resource when a server-side apply is rejected#642

Merged
gianlucam76 merged 1 commit into
projectsveltos:mainfrom
gianlucam76:yaml-force
Jul 15, 2026
Merged

feat: allow recreating a resource when a server-side apply is rejected#642
gianlucam76 merged 1 commit into
projectsveltos:mainfrom
gianlucam76:yaml-force

Conversation

@gianlucam76

Copy link
Copy Markdown
Member

Server-side apply cannot always reconcile a manifest change: if a field was set by API server defaulting (or is otherwise owned by a different/unknown field manager) and the new manifest introduces a value that conflicts with it, the apply is rejected and no patch can clear it. The concrete case that motivated this: a Deployment originally applied with no strategy gets spec.strategy.rollingUpdate defaulted by the API server; a later manifest that sets strategy.type: Recreate (without rollingUpdate) is then rejected with:

      Deployment.apps "foo" is invalid: spec.strategy.rollingUpdate: Forbidden:
      may not be specified when strategy `type` is 'Recreate'

UpdateResource gains a forceRecreate parameter (default caller behavior unchanged when false). When true, and the apply fails with an error that only a delete+recreate can resolve, the object is deleted, the code waits for it to be gone, and the apply is retried as a create. Error error-text patterns for admission/CEL-enforced immutable fields.

Deliberately excludes apierrors.IsConflict. Conflicts are already retried in place by the existing retry.RetryOnConflict wrapper. This also never applies to CustomResourceDefinitions, since deleting one cascades to every instance of it.

For pull mode, ConfigurationBundleSpec gains a matching Force field, and pullmode.WithResourceInfo takes a force argument alongside the existing tier/skipNamespaceCreation, so the option can ride along on the same per-PolicyRef/per-KustomizationRef granularity as those two.

This is a library-only change with no new caller opting in yet (forceRecreate/Force default to false everywhere). addon-controller and sveltos-applier will consume this in follow-up PRs to expose it as a user-facing option on PolicyRef/KustomizationRef.

@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Server-side apply cannot always reconcile a manifest change: if a field was
set by API server defaulting (or is otherwise owned by a different/unknown
field manager) and the new manifest introduces a value that conflicts with
it, the apply is rejected and no patch can clear it. The concrete case that
motivated this: a Deployment originally applied with no `strategy` gets
`spec.strategy.rollingUpdate` defaulted by the API server; a later manifest
that sets `strategy.type: Recreate` (without `rollingUpdate`) is then
rejected with:

```
      Deployment.apps "foo" is invalid: spec.strategy.rollingUpdate: Forbidden:
      may not be specified when strategy `type` is 'Recreate'
```

`UpdateResource` gains a `forceRecreate` parameter (default caller behavior
unchanged when false). When true, and the apply fails with an error that
only a delete+recreate can resolve, the object is deleted, the code waits
for it to be gone, and the apply is retried as a create. Error
error-text patterns for admission/CEL-enforced immutable fields.

Deliberately excludes `apierrors.IsConflict`. Conflicts are already retried
in place by the existing `retry.RetryOnConflict` wrapper.
This also never applies to CustomResourceDefinitions, since deleting one cascades
to every instance of it.

For pull mode, `ConfigurationBundleSpec` gains a matching `Force` field, and
`pullmode.WithResourceInfo` takes a `force` argument alongside the existing
`tier`/`skipNamespaceCreation`, so the option can ride along on the same
per-PolicyRef/per-KustomizationRef granularity as those two.

This is a library-only change with no new caller opting in yet
(`forceRecreate`/`Force` default to false everywhere). addon-controller and
sveltos-applier will consume this in follow-up PRs to expose it as a
user-facing option on `PolicyRef`/`KustomizationRef`.
@gianlucam76
gianlucam76 merged commit 148c083 into projectsveltos:main Jul 15, 2026
4 checks passed
@gianlucam76
gianlucam76 deleted the yaml-force branch July 15, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants