@@ -5,7 +5,6 @@ package controllers
5
5
6
6
import (
7
7
"context"
8
- "encoding/json"
9
8
"fmt"
10
9
"net"
11
10
"strconv"
@@ -16,6 +15,7 @@ import (
16
15
"k8s.io/apimachinery/pkg/types"
17
16
"k8s.io/client-go/util/retry"
18
17
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
18
+ "sigs.k8s.io/cluster-api/util/patch"
19
19
"sigs.k8s.io/controller-runtime/pkg/client"
20
20
21
21
"github.com/clastix/cluster-api-control-plane-provider-kamaji/api/v1alpha1"
@@ -125,7 +125,7 @@ func (r *KamajiControlPlaneReconciler) checkOrPatchGenericCluster(ctx context.Co
125
125
return nil
126
126
}
127
127
128
- //+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters;hetznerclusters;kubevirtclusters;nutanixclusters;packetclusters;ionoscloudclusters,verbs=patch
128
+ //+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters;hetznerclusters;kubevirtclusters;nutanixclusters;packetclusters;ionoscloudclusters,verbs=patch;get;list;watch
129
129
//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=kubevirtclusters/status;nutanixclusters/status;packetclusters/status,verbs=patch
130
130
131
131
func (r * KamajiControlPlaneReconciler ) patchGenericCluster (ctx context.Context , cluster capiv1beta1.Cluster , endpoint string , port int64 , patchStatus bool ) error {
@@ -135,37 +135,30 @@ func (r *KamajiControlPlaneReconciler) patchGenericCluster(ctx context.Context,
135
135
infraCluster .SetName (cluster .Spec .InfrastructureRef .Name )
136
136
infraCluster .SetNamespace (cluster .Spec .InfrastructureRef .Namespace )
137
137
138
- specPatch , err := json .Marshal (map [string ]interface {}{
139
- "spec" : map [string ]interface {}{
140
- "controlPlaneEndpoint" : map [string ]interface {}{
141
- "host" : endpoint ,
142
- "port" : port ,
143
- },
144
- },
145
- })
146
- if err != nil {
147
- return errors .Wrap (err , fmt .Sprintf ("unable to marshal %s spec patch" , infraCluster .GetKind ()))
138
+ if err := r .client .Get (ctx , types.NamespacedName {Name : infraCluster .GetName (), Namespace : infraCluster .GetNamespace ()}, & infraCluster ); err != nil {
139
+ return errors .Wrap (err , fmt .Sprintf ("cannot retrieve the %s resource" , infraCluster .GetKind ()))
148
140
}
149
141
150
- if err = r .client .Patch (ctx , & infraCluster , client .RawPatch (types .MergePatchType , specPatch )); err != nil {
151
- return errors .Wrap (err , fmt .Sprintf ("cannot perform PATCH update for the %s resource" , infraCluster .GetKind ()))
142
+ patchHelper , err := patch .NewHelper (& infraCluster , r .client )
143
+ if err != nil {
144
+ return errors .Wrap (err , "unable to create patch helper" )
152
145
}
153
146
154
- if ! patchStatus {
155
- return nil
147
+ if err = unstructured .SetNestedMap (infraCluster .Object , map [string ]interface {}{
148
+ "host" : endpoint ,
149
+ "port" : port ,
150
+ }, "spec" , "controlPlaneEndpoint" ); err != nil {
151
+ return errors .Wrap (err , fmt .Sprintf ("unable to set unstructured %s spec patch" , infraCluster .GetKind ()))
156
152
}
157
153
158
- statusPatch , err := json .Marshal (map [string ]interface {}{
159
- "status" : map [string ]interface {}{
160
- "ready" : true ,
161
- },
162
- })
163
- if err != nil {
164
- return errors .Wrap (err , fmt .Sprintf ("unable to marshal %s status patch" , infraCluster .GetKind ()))
154
+ if patchStatus {
155
+ if err = unstructured .SetNestedField (infraCluster .Object , true , "status" , "ready" ); err != nil {
156
+ return errors .Wrap (err , fmt .Sprintf ("unable to set unstructured %s status patch" , infraCluster .GetKind ()))
157
+ }
165
158
}
166
159
167
- if err = r . client . Status (). Patch (ctx , & infraCluster , client . RawPatch ( types . MergePatchType , statusPatch ) ); err != nil {
168
- return errors .Wrap (err , fmt .Sprintf ("cannot perform PATCH update for the %s status " , infraCluster .GetKind ()))
160
+ if err = patchHelper . Patch (ctx , & infraCluster ); err != nil {
161
+ return errors .Wrap (err , fmt .Sprintf ("cannot perform PATCH update for the %s resource " , infraCluster .GetKind ()))
169
162
}
170
163
171
164
return nil
@@ -184,14 +177,19 @@ func (r *KamajiControlPlaneReconciler) checkGenericCluster(ctx context.Context,
184
177
return errors .Wrap (err , fmt .Sprintf ("cannot retrieve the %s resource" , gkc .GetKind ()))
185
178
}
186
179
187
- controlPlaneEndpointUn := gkc .Object [ "spec" ].( map [ string ] interface {})[ "controlPlaneEndpoint" ] //nolint:forcetypeassert
188
- if controlPlaneEndpointUn = = nil {
189
- return * NewUnmanagedControlPlaneAddressError ( gkc . GetKind () )
180
+ cpHost , _ , err := unstructured . NestedString ( gkc .Object , "spec" , "controlPlaneEndpoint" , "host" )
181
+ if err ! = nil {
182
+ return errors . Wrap ( err , "cannot extract control plane endpoint host" )
190
183
}
191
184
192
- controlPlaneEndpoint := controlPlaneEndpointUn .(map [string ]interface {}) //nolint:forcetypeassert
185
+ if cpHost == "" {
186
+ return * NewUnmanagedControlPlaneAddressError (gkc .GetKind ())
187
+ }
193
188
194
- cpHost , cpPort := controlPlaneEndpoint ["host" ].(string ), controlPlaneEndpoint ["port" ].(int64 ) //nolint:forcetypeassert
189
+ cpPort , _ , err := unstructured .NestedInt64 (gkc .Object , "spec" , "controlPlaneEndpoint" , "port" )
190
+ if err != nil {
191
+ return errors .Wrap (err , "cannot extract control plane endpoint host" )
192
+ }
195
193
196
194
if len (cpHost ) == 0 && cpPort == 0 {
197
195
return * NewUnmanagedControlPlaneAddressError (gkc .GetKind ())
@@ -208,7 +206,7 @@ func (r *KamajiControlPlaneReconciler) checkGenericCluster(ctx context.Context,
208
206
return nil
209
207
}
210
208
211
- //+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=openstackclusters,verbs=patch
209
+ //+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=openstackclusters,verbs=patch;get;list;watch
212
210
213
211
func (r * KamajiControlPlaneReconciler ) patchOpenStackCluster (ctx context.Context , cluster capiv1beta1.Cluster , endpoint string , port int64 ) error {
214
212
osc := unstructured.Unstructured {}
@@ -217,17 +215,23 @@ func (r *KamajiControlPlaneReconciler) patchOpenStackCluster(ctx context.Context
217
215
osc .SetName (cluster .Spec .InfrastructureRef .Name )
218
216
osc .SetNamespace (cluster .Spec .InfrastructureRef .Namespace )
219
217
220
- mergePatch , err := json .Marshal (map [string ]interface {}{
221
- "spec" : map [string ]interface {}{
222
- "apiServerFixedIP" : endpoint ,
223
- "apiServerPort" : port ,
224
- },
225
- })
218
+ if err := r .client .Get (ctx , types.NamespacedName {Name : osc .GetName (), Namespace : osc .GetNamespace ()}, & osc ); err != nil {
219
+ return errors .Wrap (err , fmt .Sprintf ("cannot retrieve the %s resource" , osc .GetKind ()))
220
+ }
221
+
222
+ patchHelper , err := patch .NewHelper (& osc , r .client )
226
223
if err != nil {
227
- return errors .Wrap (err , "unable to marshal OpenStackCluster patch" )
224
+ return errors .Wrap (err , "unable to create patch helper" )
225
+ }
226
+
227
+ if err = unstructured .SetNestedMap (osc .Object , map [string ]interface {}{
228
+ "apiServerFixedIP" : endpoint ,
229
+ "apiServerPort" : port ,
230
+ }, "spec" ); err != nil {
231
+ return errors .Wrap (err , fmt .Sprintf ("unable to set unstructured %s spec patch" , osc .GetKind ()))
228
232
}
229
233
230
- if err = r . client . Patch (ctx , & osc , client . RawPatch ( types . MergePatchType , mergePatch ) ); err != nil {
234
+ if err = patchHelper . Patch (ctx , & osc ); err != nil {
231
235
return errors .Wrap (err , "cannot perform PATCH update for the OpenStackCluster resource" )
232
236
}
233
237
0 commit comments