@@ -22,6 +22,7 @@ import (
2222 rdeType "github.com/vmware/cluster-api-provider-cloud-director/pkg/vcdtypes/rde_type_1_1_0"
2323 "github.com/vmware/cluster-api-provider-cloud-director/release"
2424 "github.com/vmware/go-vcloud-director/v2/govcd"
25+ "github.com/vmware/go-vcloud-director/v2/types/v56"
2526 apierrors "k8s.io/apimachinery/pkg/api/errors"
2627 "k8s.io/apimachinery/pkg/runtime"
2728 "k8s.io/klog"
@@ -229,10 +230,14 @@ func validateDerivedRDEProperties(vcdCluster *infrav1.VCDCluster, infraID string
229230
230231// TODO: Remove uncommented code when decision to only keep capi.yaml as part of RDE spec is finalized
231232func (r * VCDClusterReconciler ) constructCapvcdRDE (ctx context.Context , cluster * clusterv1.Cluster ,
232- vcdCluster * infrav1.VCDCluster ) (* swagger.DefinedEntity , error ) {
233- org := vcdCluster .Spec .Org
234- vdc := vcdCluster .Spec .Ovdc
233+ vcdCluster * infrav1.VCDCluster , vdc * types.Vdc , vcdOrg * types.Org ) (* swagger.DefinedEntity , error ) {
235234
235+ if vdc == nil {
236+ return nil , fmt .Errorf ("VDC cannot be nil" )
237+ }
238+ if vcdOrg == nil {
239+ return nil , fmt .Errorf ("org cannot be nil" )
240+ }
236241 kcpList , err := getAllKubeadmControlPlaneForCluster (ctx , r .Client , * cluster )
237242 if err != nil {
238243 return nil , fmt .Errorf ("error getting KubeadmControlPlane objects for cluster [%s]: [%v]" , vcdCluster .Name , err )
@@ -256,8 +261,8 @@ func (r *VCDClusterReconciler) constructCapvcdRDE(ctx context.Context, cluster *
256261 ApiVersion : capisdk .CAPVCDClusterEntityApiVersion ,
257262 Metadata : rdeType.Metadata {
258263 Name : vcdCluster .Name ,
259- Org : org ,
260- Vdc : vdc ,
264+ Org : vcdOrg . Name ,
265+ Vdc : vdc . Name ,
261266 Site : vcdCluster .Spec .Site ,
262267 },
263268 Spec : rdeType.CAPVCDSpec {},
@@ -283,9 +288,19 @@ func (r *VCDClusterReconciler) constructCapvcdRDE(ctx context.Context, cluster *
283288 },
284289 ParentUID : vcdCluster .Spec .ParentUID ,
285290 VcdProperties : rdeType.VCDProperties {
286- Site : vcdCluster .Spec .Site ,
287- Org : org ,
288- Vdc : vdc ,
291+ Site : vcdCluster .Spec .Site ,
292+ Org : []rdeType.Org {
293+ rdeType.Org {
294+ Name : vcdOrg .Name ,
295+ ID : vcdOrg .ID ,
296+ },
297+ },
298+ Ovdc : []rdeType.Ovdc {
299+ rdeType.Ovdc {
300+ Name : vdc .Name ,
301+ ID : vdc .ID ,
302+ },
303+ },
289304 OvdcNetwork : vcdCluster .Spec .OvdcNetwork ,
290305 },
291306 CapiStatusYaml : "" ,
@@ -316,7 +331,11 @@ func (r *VCDClusterReconciler) constructCapvcdRDE(ctx context.Context, cluster *
316331func (r * VCDClusterReconciler ) constructAndCreateRDEFromCluster (ctx context.Context , workloadVCDClient * vcdsdk.Client , cluster * clusterv1.Cluster , vcdCluster * infrav1.VCDCluster ) (string , error ) {
317332 log := ctrl .LoggerFrom (ctx )
318333
319- rde , err := r .constructCapvcdRDE (ctx , cluster , vcdCluster )
334+ org , err := workloadVCDClient .VCDClient .GetOrgByName (vcdCluster .Spec .Org )
335+ if err != nil {
336+ return "" , fmt .Errorf ("failed to get org by name [%s]" , vcdCluster .Spec .Org )
337+ }
338+ rde , err := r .constructCapvcdRDE (ctx , cluster , vcdCluster , workloadVCDClient .VDC .Vdc , org .Org )
320339 if err != nil {
321340 return "" , fmt .Errorf ("error occurred while constructing RDE payload for the cluster [%s]: [%v]" , vcdCluster .Name , err )
322341 }
@@ -341,19 +360,26 @@ func (r *VCDClusterReconciler) constructAndCreateRDEFromCluster(ctx context.Cont
341360}
342361
343362func (r * VCDClusterReconciler ) reconcileRDE (ctx context.Context , cluster * clusterv1.Cluster ,
344- vcdCluster * infrav1.VCDCluster , workloadVCDClient * vcdsdk.Client ) error {
363+ vcdCluster * infrav1.VCDCluster , workloadVCDClient * vcdsdk.Client , vappID string , updateExternalID bool ) error {
345364 log := ctrl .LoggerFrom (ctx )
346365
366+ org , err := workloadVCDClient .VCDClient .GetOrgByName (vcdCluster .Spec .Org )
367+ if err != nil {
368+ return fmt .Errorf ("failed to get org by name [%s]" , vcdCluster .Spec .Org )
369+ }
370+ if org == nil || org .Org == nil {
371+ return fmt .Errorf ("found nil org when getting org by name [%s]" , vcdCluster .Spec .Org )
372+ }
347373 capvcdRdeManager := capisdk .NewCapvcdRdeManager (workloadVCDClient , vcdCluster .Status .InfraId )
348374 _ , capvcdSpec , capvcdMetadata , capvcdStatus , err := capvcdRdeManager .GetCAPVCDEntity (ctx , vcdCluster .Status .InfraId )
349375 if err != nil {
350376 return fmt .Errorf ("failed to get RDE with ID [%s] for cluster [%s]: [%v]" , vcdCluster .Status .InfraId , vcdCluster .Name , err )
351377 }
352378 // TODO(VCDA-3107): Should we be updating org and vdc information here.
353379 metadataPatch := make (map [string ]interface {})
354- org := vcdCluster . Spec . Org
355- if org != capvcdMetadata .Org {
356- metadataPatch ["Org" ] = org
380+
381+ if org . Org . Name != capvcdMetadata .Org {
382+ metadataPatch ["Org" ] = org . Org . Name
357383 }
358384
359385 vdc := vcdCluster .Spec .Ovdc
@@ -525,9 +551,19 @@ func (r *VCDClusterReconciler) reconcileRDE(ctx context.Context, cluster *cluste
525551 }
526552
527553 vcdResources := rdeType.VCDProperties {
528- Site : vcdCluster .Spec .Site ,
529- Org : vcdCluster .Spec .Org ,
530- Vdc : vcdCluster .Spec .Ovdc ,
554+ Site : vcdCluster .Spec .Site ,
555+ Org : []rdeType.Org {
556+ rdeType.Org {
557+ Name : org .Org .Name ,
558+ ID : org .Org .ID ,
559+ },
560+ },
561+ Ovdc : []rdeType.Ovdc {
562+ rdeType.Ovdc {
563+ Name : workloadVCDClient .VDC .Vdc .Name ,
564+ ID : workloadVCDClient .VDC .Vdc .Name ,
565+ },
566+ },
531567 OvdcNetwork : vcdCluster .Spec .OvdcNetwork ,
532568 }
533569 if ! reflect .DeepEqual (vcdResources , capvcdStatus .VcdProperties ) {
@@ -547,7 +583,7 @@ func (r *VCDClusterReconciler) reconcileRDE(ctx context.Context, cluster *cluste
547583 }
548584 }
549585
550- updatedRDE , err := capvcdRdeManager .PatchRDE (ctx , specPatch , metadataPatch , capvcdStatusPatch , vcdCluster .Status .InfraId )
586+ updatedRDE , err := capvcdRdeManager .PatchRDE (ctx , specPatch , metadataPatch , capvcdStatusPatch , vcdCluster .Status .InfraId , vappID , updateExternalID )
551587 if err != nil {
552588 return fmt .Errorf ("failed to update defined entity with ID [%s] for cluster [%s]: [%v]" , vcdCluster .Status .InfraId , vcdCluster .Name , err )
553589 }
@@ -696,7 +732,7 @@ func (r *VCDClusterReconciler) reconcileNormal(ctx context.Context, cluster *clu
696732 return ctrl.Result {}, errors .Wrapf (err , "failed to upgrade RDE [%s]" , infraID )
697733 }
698734 // calling reconcileRDE here to avoid delay in updating the RDE contents
699- if err = r .reconcileRDE (ctx , cluster , vcdCluster , workloadVCDClient ); err != nil {
735+ if err = r .reconcileRDE (ctx , cluster , vcdCluster , workloadVCDClient , "" , false ); err != nil {
700736 // TODO: can we recover the RDE to a proper state if RDE fails to reconcile?
701737 log .Error (err , "failed to reconcile RDE after upgrading RDE" , "rdeID" , infraID )
702738 return ctrl.Result {}, errors .Wrapf (err , "failed to reconcile RDE after upgrading RDE [%s]" , infraID )
@@ -844,7 +880,7 @@ func (r *VCDClusterReconciler) reconcileNormal(ctx context.Context, cluster *clu
844880 if ! strings .HasPrefix (vcdCluster .Status .InfraId , NoRdePrefix ) {
845881 _ , resp , _ , err := workloadVCDClient .APIClient .DefinedEntityApi .GetDefinedEntity (ctx , vcdCluster .Status .InfraId )
846882 if err == nil && resp != nil && resp .StatusCode == http .StatusOK {
847- if err = r .reconcileRDE (ctx , cluster , vcdCluster , workloadVCDClient ); err != nil {
883+ if err = r .reconcileRDE (ctx , cluster , vcdCluster , workloadVCDClient , "" , false ); err != nil {
848884 log .Error (err , "Error occurred during RDE reconciliation" ,
849885 "InfraId" , vcdCluster .Status .InfraId )
850886 }
@@ -891,6 +927,14 @@ func (r *VCDClusterReconciler) reconcileNormal(ctx context.Context, cluster *clu
891927 if clusterVApp == nil || clusterVApp .VApp == nil {
892928 return ctrl.Result {}, errors .Wrapf (err , "found nil value for VApp [%s]" , vcdCluster .Name )
893929 }
930+ if ! strings .HasPrefix (vcdCluster .Status .InfraId , NoRdePrefix ) {
931+ if err := r .reconcileRDE (ctx , cluster , vcdCluster , workloadVCDClient , clusterVApp .VApp .ID , true ); err != nil {
932+ log .Error (err , "failed to add VApp ID to RDE" , "rdeID" , infraID , "vappID" , clusterVApp .VApp .ID )
933+ return ctrl.Result {}, errors .Wrapf (err , "failed to update RDE [%s] with VApp ID [%s]: [%v]" , vcdCluster .Status .InfraId , clusterVApp .VApp .ID , err )
934+ }
935+ log .Info ("successfully updated external ID of RDE with VApp ID" , "infraID" , infraID , "vAppID" , clusterVApp .VApp .ID )
936+ }
937+
894938 if metadataMap != nil && len (metadataMap ) > 0 && ! vcdCluster .Status .VAppMetadataUpdated {
895939 if err := vdcManager .AddMetadataToVApp (vcdCluster .Name , metadataMap ); err != nil {
896940 return ctrl.Result {}, fmt .Errorf ("unable to add metadata [%s] to vApp [%s]: [%v]" , metadataMap , vcdCluster .Name , err )
0 commit comments