Skip to content

Commit

Permalink
Support --force apply
Browse files Browse the repository at this point in the history
Allow passing --force to kubectl apply. Useful when dealing with
immutable field changes in resources.

Signed-off-by: Aurel Canciu <[email protected]>
  • Loading branch information
relu committed Feb 13, 2021
1 parent 527af26 commit 8b21a4f
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 5 deletions.
8 changes: 7 additions & 1 deletion api/v1beta1/kustomization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ limitations under the License.
package v1beta1

import (
"time"

apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apimeta "k8s.io/apimachinery/pkg/api/meta"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -127,6 +128,11 @@ type KustomizationSpec struct {
// +kubebuilder:validation:Enum=none;client;server
// +optional
Validation string `json:"validation,omitempty"`

// Force instructs the controller to recreate resources in the situation
// when dealing with immutable field changes.
// +kubebuilder:default:=false +optional
Force bool `json:"force,omitempty"`
}

// Decryption defines how decryption is handled for Kubernetes manifests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ spec:
- name
type: object
type: array
force:
default: false
description: Force instructs the controller to re-create immutable
resources.
type: boolean
healthChecks:
description: A list of resources to be included in the health assessment.
items:
Expand Down
11 changes: 11 additions & 0 deletions config/testdata/force/job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: batch/v1
kind: Job
metadata:
name: test
spec:
template:
spec:
containers:
- name: test
image: alpine:3.12
restartPolicy: Never
6 changes: 6 additions & 0 deletions config/testdata/force/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- source.yaml
- test-job.yaml
- job.yaml
9 changes: 9 additions & 0 deletions config/testdata/force/source.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: force
spec:
interval: 10m
url: https://gist.github.com/cd83f83eebee3217d02ee5d3b97a9908.git
ref:
branch: master
14 changes: 14 additions & 0 deletions config/testdata/force/test-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: test-job
spec:
interval: 5m
path: "./"
prune: true
sourceRef:
kind: GitRepository
name: force
validation: server
force: true
timeout: 2m
8 changes: 4 additions & 4 deletions controllers/kustomization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,8 @@ func (r *KustomizationReconciler) validate(ctx context.Context, kustomization ku
applyCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()

cmd := fmt.Sprintf("cd %s && kubectl apply -f %s.yaml --timeout=%s --dry-run=%s --cache-dir=/tmp",
dirPath, kustomization.GetUID(), kustomization.GetTimeout().String(), kustomization.Spec.Validation)
cmd := fmt.Sprintf("cd %s && kubectl apply -f %s.yaml --timeout=%s --dry-run=%s --cache-dir=/tmp --force=%t",
dirPath, kustomization.GetUID(), kustomization.GetTimeout().String(), kustomization.Spec.Validation, kustomization.Spec.Force)

if kustomization.Spec.KubeConfig != nil {
kubeConfig, err := imp.WriteKubeConfig(ctx)
Expand Down Expand Up @@ -589,8 +589,8 @@ func (r *KustomizationReconciler) apply(ctx context.Context, kustomization kusto
defer cancel()
fieldManager := "kustomize-controller"

cmd := fmt.Sprintf("cd %s && kubectl apply --field-manager=%s -f %s.yaml --timeout=%s --cache-dir=/tmp",
dirPath, fieldManager, kustomization.GetUID(), kustomization.Spec.Interval.Duration.String())
cmd := fmt.Sprintf("cd %s && kubectl apply --field-manager=%s -f %s.yaml --timeout=%s --cache-dir=/tmp --force=%t",
dirPath, fieldManager, kustomization.GetUID(), kustomization.Spec.Interval.Duration.String(), kustomization.Spec.Force)

if kustomization.Spec.KubeConfig != nil {
kubeConfig, err := imp.WriteKubeConfig(ctx)
Expand Down
1 change: 1 addition & 0 deletions controllers/kustomization_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ var _ = Describe("KustomizationReconciler", func() {
Suspend: false,
Timeout: nil,
Validation: "client",
Force: false,
PostBuild: &kustomizev1.PostBuild{
Substitute: map[string]string{"region": "eu-central-1"},
},
Expand Down
24 changes: 24 additions & 0 deletions docs/api/kustomize.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,18 @@ string
The validation strategy can be &lsquo;client&rsquo; (local dry-run), &lsquo;server&rsquo; (APIServer dry-run) or &lsquo;none&rsquo;.</p>
</td>
</tr>
<tr>
<td>
<code>force</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Force instructs the controller to re-create immutable resources.</p>
</td>
</tr>
</table>
</td>
</tr>
Expand Down Expand Up @@ -763,6 +775,18 @@ string
The validation strategy can be &lsquo;client&rsquo; (local dry-run), &lsquo;server&rsquo; (APIServer dry-run) or &lsquo;none&rsquo;.</p>
</td>
</tr>
<tr>
<td>
<code>force</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Force instructs the controller to re-create immutable resources.</p>
</td>
</tr>
</tbody>
</table>
</div>
Expand Down

0 comments on commit 8b21a4f

Please sign in to comment.