Skip to content

Commit

Permalink
Merge pull request #192 from fluxcd/ssa-force-fix
Browse files Browse the repository at this point in the history
ssa: Force apply on invalid and conflict errors
  • Loading branch information
stefanprodan authored Dec 4, 2021
2 parents c38e659 + 0c386be commit 283cbad
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 6 deletions.
55 changes: 53 additions & 2 deletions ssa/manager_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ func TestApply(t *testing.T) {
manager.SetOwnerLabels(objects, "app1", "default")

configMapName, configMap := getFirstObject(objects, "ConfigMap", id)
secretName, secret := getFirstObject(objects, "Secret", id)
crbName, crb := getFirstObject(objects, "ClusterRoleBinding", id)

t.Run("creates objects in order", func(t *testing.T) {
// create objects
Expand Down Expand Up @@ -137,6 +135,29 @@ func TestApply(t *testing.T) {
t.Errorf("Mismatch from expected value (-want +got):\n%s", diff)
}
})
}

func TestApply_Force(t *testing.T) {
timeout := 10 * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

id := generateName("apply")
objects, err := readManifest("testdata/test1.yaml", id)
if err != nil {
t.Fatal(err)
}

manager.SetOwnerLabels(objects, "app1", "default")

secretName, secret := getFirstObject(objects, "Secret", id)
crbName, crb := getFirstObject(objects, "ClusterRoleBinding", id)
stName, st := getFirstObject(objects, "StorageClass", id)

// create objects
if _, err := manager.ApplyAllStaged(ctx, objects, DefaultApplyOptions()); err != nil {
t.Fatal(err)
}

t.Run("fails to apply immutable secret", func(t *testing.T) {
// update a value in the secret
Expand Down Expand Up @@ -220,6 +241,36 @@ func TestApply(t *testing.T) {
}
}
})

t.Run("recreates immutable StorageClass", func(t *testing.T) {
// update parameters
err = unstructured.SetNestedField(st.Object, "true", "parameters", "encrypted")
if err != nil {
t.Fatal(err)
}

// apply and expect to fail
_, err := manager.ApplyAllStaged(ctx, objects, DefaultApplyOptions())
if err == nil {
t.Fatal("Expected error got none")
}

// force apply
changeSet, err := manager.ApplyAllStaged(ctx, objects, ApplyOptions{Force: true, WaitTimeout: timeout})
if err != nil {
t.Fatal(err)
}

// verify the storage class was recreated
for _, entry := range changeSet.Entries {
if entry.Subject == stName {
if diff := cmp.Diff(string(CreatedAction), entry.Action); diff != "" {
t.Errorf("Mismatch from expected value (-want +got):\n%s", diff)
}
break
}
}
})
}

func TestApply_SetNativeKindsDefaults(t *testing.T) {
Expand Down
12 changes: 12 additions & 0 deletions ssa/testdata/test1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ subjects:
- kind: ServiceAccount
name: "%[1]s"
namespace: "%[1]s"
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: "%[1]s"
parameters:
encrypted: "false"
fsType: ext4
type: gp2
provisioner: kubernetes.io/aws-ebs
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
9 changes: 5 additions & 4 deletions ssa/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
autoscalingv1 "k8s.io/api/autoscaling/v2beta1"
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
apiruntime "k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -207,10 +208,10 @@ func IsKustomization(object *unstructured.Unstructured) bool {
}

func isImmutableError(err error) bool {
for _, s := range []string{"field is immutable", "cannot change roleRef"} {
if strings.Contains(err.Error(), s) {
return true
}
// Detect immutability like kubectl does
// https://github.com/kubernetes/kubectl/blob/8165f83007/pkg/cmd/apply/patcher.go#L201
if errors.IsConflict(err) || errors.IsInvalid(err) {
return true
}
return false
}
Expand Down

0 comments on commit 283cbad

Please sign in to comment.