Skip to content

Commit

Permalink
[v0.5] Prevent dropping unknown cluster fields (rancher#516)
Browse files Browse the repository at this point in the history
* Prevents dropping unknown cluster fields

Signed-off-by: Dharmit Shah <dharmit.shah@suse.com>

* add test for v3 cluster mutator & add rke to replace in go.mod

adding rke to replace section will avoid pulling in rc versions
when updating pkg/apis in webhook
  • Loading branch information
kinarashah authored Oct 3, 2024
1 parent b78e887 commit 602351a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.0
toolchain go1.22.7

replace (
github.com/rancher/rke => github.com/rancher/rke v1.6.2
k8s.io/api => k8s.io/api v0.30.1
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.1
k8s.io/apimachinery => k8s.io/apimachinery v0.30.1
Expand Down
9 changes: 8 additions & 1 deletion pkg/resources/management.cattle.io/v3/cluster/mutator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cluster

import (
"encoding/json"
"fmt"
"reflect"

Expand Down Expand Up @@ -59,6 +60,10 @@ func (m *ManagementClusterMutator) Admit(request *admission.Request) (*admission
if err != nil {
return nil, fmt.Errorf("failed to get old and new clusters from request: %w", err)
}
newClusterRaw, err := json.Marshal(newCluster)
if err != nil {
return nil, fmt.Errorf("unable to re-marshal new cluster: %w", err)
}
// no need to mutate the local cluster, or imported cluster which represents a KEv2 cluster (GKE/EKS/AKS) or v1 Provisioning Cluster
if newCluster.Name == "local" || newCluster.Spec.RancherKubernetesEngineConfig == nil {
return admission.ResponseAllowed(), nil
Expand Down Expand Up @@ -94,7 +99,9 @@ func (m *ManagementClusterMutator) Admit(request *admission.Request) (*admission
}

response := &admissionv1.AdmissionResponse{}
if err := patch.CreatePatch(request.Object.Raw, newCluster, response); err != nil {
// we use the re-marshalled new cluster to make sure that the patch doesn't drop "unknown" fields which were
// in the json, but not in the cluster struct. This can occur due to out of date RKE versions
if err := patch.CreatePatch(newClusterRaw, newCluster, response); err != nil {
return response, fmt.Errorf("failed to create patch: %w", err)
}
response.Allowed = true
Expand Down
46 changes: 46 additions & 0 deletions pkg/resources/management.cattle.io/v3/cluster/mutator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cluster

import (
"encoding/json"
"testing"

v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3"
"github.com/rancher/webhook/pkg/admission"
data2 "github.com/rancher/wrangler/v3/pkg/data"
"github.com/stretchr/testify/assert"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/runtime"
)

func TestAdmitPreserveUnknownFields(t *testing.T) {
cluster := &v3.Cluster{}
data, err := data2.Convert(cluster)
assert.Nil(t, err)

data.SetNested("test", "spec", "rancherKubernetesEngineConfig", "network", "aciNetworkProvider", "apicUserKeyTest")
raw, err := json.Marshal(data)
assert.Nil(t, err)

request := &admission.Request{
AdmissionRequest: admissionv1.AdmissionRequest{
Object: runtime.RawExtension{
Raw: raw,
},
OldObject: runtime.RawExtension{
Raw: raw,
},
},
}

m := ManagementClusterMutator{}

request.Operation = admissionv1.Create
response, err := m.Admit(request)
assert.Nil(t, err)
assert.Nil(t, response.Patch)

request.Operation = admissionv1.Update
response, err = m.Admit(request)
assert.Nil(t, err)
assert.Nil(t, response.Patch)
}

0 comments on commit 602351a

Please sign in to comment.