@@ -17,6 +17,10 @@ limitations under the License.
17
17
package v1alpha4
18
18
19
19
import (
20
+ "reflect"
21
+
22
+ "github.com/pkg/errors"
23
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
20
24
"k8s.io/apimachinery/pkg/runtime"
21
25
"k8s.io/apimachinery/pkg/util/validation/field"
22
26
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -34,8 +38,8 @@ func (r *OpenStackCluster) SetupWebhookWithManager(mgr manager.Manager) error {
34
38
Complete ()
35
39
}
36
40
37
- // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackcluster ,versions=v1alpha4,name=validation.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
38
- // +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackcluster ,versions=v1alpha4,name=default.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
41
+ // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclusters ,versions=v1alpha4,name=validation.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
42
+ // +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-openstackcluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclusters ,versions=v1alpha4,name=default.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
39
43
40
44
var (
41
45
_ webhook.Defaulter = & OpenStackCluster {}
@@ -64,10 +68,34 @@ func (r *OpenStackCluster) ValidateCreate() error {
64
68
func (r * OpenStackCluster ) ValidateUpdate (old runtime.Object ) error {
65
69
var allErrs field.ErrorList
66
70
71
+ newOpenStackCluster , err := runtime .DefaultUnstructuredConverter .ToUnstructured (r )
72
+ if err != nil {
73
+ return apierrors .NewInvalid (GroupVersion .WithKind ("OpenStackCluster" ).GroupKind (), r .Name , field.ErrorList {
74
+ field .InternalError (nil , errors .Wrap (err , "failed to convert new OpenStackCluster to unstructured object" )),
75
+ })
76
+ }
77
+ oldOpenStackCluster , err := runtime .DefaultUnstructuredConverter .ToUnstructured (old )
78
+ if err != nil {
79
+ return apierrors .NewInvalid (GroupVersion .WithKind ("OpenStackCluster" ).GroupKind (), r .Name , field.ErrorList {
80
+ field .InternalError (nil , errors .Wrap (err , "failed to convert old OpenStackCluster to unstructured object" )),
81
+ })
82
+ }
83
+
67
84
if r .Spec .IdentityRef != nil && r .Spec .IdentityRef .Kind != defaultIdentityRefKind {
68
85
allErrs = append (allErrs , field .Forbidden (field .NewPath ("spec" , "identityRef" , "kind" ), "must be a Secret" ))
69
86
}
70
87
88
+ newOpenStackClusterSpec := newOpenStackCluster ["spec" ].(map [string ]interface {})
89
+ oldOpenStackClusterSpec := oldOpenStackCluster ["spec" ].(map [string ]interface {})
90
+
91
+ // allow changes to ControlPlaneEndpoint
92
+ delete (oldOpenStackClusterSpec , "controlPlaneEndpoint" )
93
+ delete (newOpenStackClusterSpec , "controlPlaneEndpoint" )
94
+
95
+ if ! reflect .DeepEqual (oldOpenStackClusterSpec , newOpenStackClusterSpec ) {
96
+ allErrs = append (allErrs , field .Forbidden (field .NewPath ("spec" ), "cannot be modified" ))
97
+ }
98
+
71
99
return aggregateObjErrors (r .GroupVersionKind ().GroupKind (), r .Name , allErrs )
72
100
}
73
101
0 commit comments