Skip to content

Commit

Permalink
[VCDA-4355] Update VcdProperties (vmware#251)
Browse files Browse the repository at this point in the history
* update schema to make org and vdcs array in vcdproperties

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* Update schema to remove vdc name property

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* Add tkg version

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* image change in infrastructure-components

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* revert image name and update examples

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* update example for tkgversion

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* image version change for debug

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* External ID update fix

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* Address comments

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* Remove tkgVersion updates

Signed-off-by: Aniruddha Shamasundar <[email protected]>

* Update examples

Signed-off-by: Aniruddha Shamasundar <[email protected]>

Signed-off-by: Aniruddha Shamasundar <[email protected]>
  • Loading branch information
Anirudh9794 authored Sep 14, 2022
1 parent 6514a4a commit d68b804
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 30 deletions.
82 changes: 63 additions & 19 deletions controllers/vcdcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
rdeType "github.com/vmware/cluster-api-provider-cloud-director/pkg/vcdtypes/rde_type_1_1_0"
"github.com/vmware/cluster-api-provider-cloud-director/release"
"github.com/vmware/go-vcloud-director/v2/govcd"
"github.com/vmware/go-vcloud-director/v2/types/v56"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog"
Expand Down Expand Up @@ -229,10 +230,14 @@ func validateDerivedRDEProperties(vcdCluster *infrav1.VCDCluster, infraID string

// TODO: Remove uncommented code when decision to only keep capi.yaml as part of RDE spec is finalized
func (r *VCDClusterReconciler) constructCapvcdRDE(ctx context.Context, cluster *clusterv1.Cluster,
vcdCluster *infrav1.VCDCluster) (*swagger.DefinedEntity, error) {
org := vcdCluster.Spec.Org
vdc := vcdCluster.Spec.Ovdc
vcdCluster *infrav1.VCDCluster, vdc *types.Vdc, vcdOrg *types.Org) (*swagger.DefinedEntity, error) {

if vdc == nil {
return nil, fmt.Errorf("VDC cannot be nil")
}
if vcdOrg == nil {
return nil, fmt.Errorf("org cannot be nil")
}
kcpList, err := getAllKubeadmControlPlaneForCluster(ctx, r.Client, *cluster)
if err != nil {
return nil, fmt.Errorf("error getting KubeadmControlPlane objects for cluster [%s]: [%v]", vcdCluster.Name, err)
Expand All @@ -256,8 +261,8 @@ func (r *VCDClusterReconciler) constructCapvcdRDE(ctx context.Context, cluster *
ApiVersion: capisdk.CAPVCDClusterEntityApiVersion,
Metadata: rdeType.Metadata{
Name: vcdCluster.Name,
Org: org,
Vdc: vdc,
Org: vcdOrg.Name,
Vdc: vdc.Name,
Site: vcdCluster.Spec.Site,
},
Spec: rdeType.CAPVCDSpec{},
Expand All @@ -283,9 +288,19 @@ func (r *VCDClusterReconciler) constructCapvcdRDE(ctx context.Context, cluster *
},
ParentUID: vcdCluster.Spec.ParentUID,
VcdProperties: rdeType.VCDProperties{
Site: vcdCluster.Spec.Site,
Org: org,
Vdc: vdc,
Site: vcdCluster.Spec.Site,
Org: []rdeType.Org{
rdeType.Org{
Name: vcdOrg.Name,
ID: vcdOrg.ID,
},
},
Ovdc: []rdeType.Ovdc{
rdeType.Ovdc{
Name: vdc.Name,
ID: vdc.ID,
},
},
OvdcNetwork: vcdCluster.Spec.OvdcNetwork,
},
CapiStatusYaml: "",
Expand Down Expand Up @@ -316,7 +331,11 @@ func (r *VCDClusterReconciler) constructCapvcdRDE(ctx context.Context, cluster *
func (r *VCDClusterReconciler) constructAndCreateRDEFromCluster(ctx context.Context, workloadVCDClient *vcdsdk.Client, cluster *clusterv1.Cluster, vcdCluster *infrav1.VCDCluster) (string, error) {
log := ctrl.LoggerFrom(ctx)

rde, err := r.constructCapvcdRDE(ctx, cluster, vcdCluster)
org, err := workloadVCDClient.VCDClient.GetOrgByName(vcdCluster.Spec.Org)
if err != nil {
return "", fmt.Errorf("failed to get org by name [%s]", vcdCluster.Spec.Org)
}
rde, err := r.constructCapvcdRDE(ctx, cluster, vcdCluster, workloadVCDClient.VDC.Vdc, org.Org)
if err != nil {
return "", fmt.Errorf("error occurred while constructing RDE payload for the cluster [%s]: [%v]", vcdCluster.Name, err)
}
Expand All @@ -341,19 +360,26 @@ func (r *VCDClusterReconciler) constructAndCreateRDEFromCluster(ctx context.Cont
}

func (r *VCDClusterReconciler) reconcileRDE(ctx context.Context, cluster *clusterv1.Cluster,
vcdCluster *infrav1.VCDCluster, workloadVCDClient *vcdsdk.Client) error {
vcdCluster *infrav1.VCDCluster, workloadVCDClient *vcdsdk.Client, vappID string, updateExternalID bool) error {
log := ctrl.LoggerFrom(ctx)

org, err := workloadVCDClient.VCDClient.GetOrgByName(vcdCluster.Spec.Org)
if err != nil {
return fmt.Errorf("failed to get org by name [%s]", vcdCluster.Spec.Org)
}
if org == nil || org.Org == nil {
return fmt.Errorf("found nil org when getting org by name [%s]", vcdCluster.Spec.Org)
}
capvcdRdeManager := capisdk.NewCapvcdRdeManager(workloadVCDClient, vcdCluster.Status.InfraId)
_, capvcdSpec, capvcdMetadata, capvcdStatus, err := capvcdRdeManager.GetCAPVCDEntity(ctx, vcdCluster.Status.InfraId)
if err != nil {
return fmt.Errorf("failed to get RDE with ID [%s] for cluster [%s]: [%v]", vcdCluster.Status.InfraId, vcdCluster.Name, err)
}
// TODO(VCDA-3107): Should we be updating org and vdc information here.
metadataPatch := make(map[string]interface{})
org := vcdCluster.Spec.Org
if org != capvcdMetadata.Org {
metadataPatch["Org"] = org

if org.Org.Name != capvcdMetadata.Org {
metadataPatch["Org"] = org.Org.Name
}

vdc := vcdCluster.Spec.Ovdc
Expand Down Expand Up @@ -525,9 +551,19 @@ func (r *VCDClusterReconciler) reconcileRDE(ctx context.Context, cluster *cluste
}

vcdResources := rdeType.VCDProperties{
Site: vcdCluster.Spec.Site,
Org: vcdCluster.Spec.Org,
Vdc: vcdCluster.Spec.Ovdc,
Site: vcdCluster.Spec.Site,
Org: []rdeType.Org{
rdeType.Org{
Name: org.Org.Name,
ID: org.Org.ID,
},
},
Ovdc: []rdeType.Ovdc{
rdeType.Ovdc{
Name: workloadVCDClient.VDC.Vdc.Name,
ID: workloadVCDClient.VDC.Vdc.Name,
},
},
OvdcNetwork: vcdCluster.Spec.OvdcNetwork,
}
if !reflect.DeepEqual(vcdResources, capvcdStatus.VcdProperties) {
Expand All @@ -547,7 +583,7 @@ func (r *VCDClusterReconciler) reconcileRDE(ctx context.Context, cluster *cluste
}
}

updatedRDE, err := capvcdRdeManager.PatchRDE(ctx, specPatch, metadataPatch, capvcdStatusPatch, vcdCluster.Status.InfraId)
updatedRDE, err := capvcdRdeManager.PatchRDE(ctx, specPatch, metadataPatch, capvcdStatusPatch, vcdCluster.Status.InfraId, vappID, updateExternalID)
if err != nil {
return fmt.Errorf("failed to update defined entity with ID [%s] for cluster [%s]: [%v]", vcdCluster.Status.InfraId, vcdCluster.Name, err)
}
Expand Down Expand Up @@ -696,7 +732,7 @@ func (r *VCDClusterReconciler) reconcileNormal(ctx context.Context, cluster *clu
return ctrl.Result{}, errors.Wrapf(err, "failed to upgrade RDE [%s]", infraID)
}
// calling reconcileRDE here to avoid delay in updating the RDE contents
if err = r.reconcileRDE(ctx, cluster, vcdCluster, workloadVCDClient); err != nil {
if err = r.reconcileRDE(ctx, cluster, vcdCluster, workloadVCDClient, "", false); err != nil {
// TODO: can we recover the RDE to a proper state if RDE fails to reconcile?
log.Error(err, "failed to reconcile RDE after upgrading RDE", "rdeID", infraID)
return ctrl.Result{}, errors.Wrapf(err, "failed to reconcile RDE after upgrading RDE [%s]", infraID)
Expand Down Expand Up @@ -844,7 +880,7 @@ func (r *VCDClusterReconciler) reconcileNormal(ctx context.Context, cluster *clu
if !strings.HasPrefix(vcdCluster.Status.InfraId, NoRdePrefix) {
_, resp, _, err := workloadVCDClient.APIClient.DefinedEntityApi.GetDefinedEntity(ctx, vcdCluster.Status.InfraId)
if err == nil && resp != nil && resp.StatusCode == http.StatusOK {
if err = r.reconcileRDE(ctx, cluster, vcdCluster, workloadVCDClient); err != nil {
if err = r.reconcileRDE(ctx, cluster, vcdCluster, workloadVCDClient, "", false); err != nil {
log.Error(err, "Error occurred during RDE reconciliation",
"InfraId", vcdCluster.Status.InfraId)
}
Expand Down Expand Up @@ -891,6 +927,14 @@ func (r *VCDClusterReconciler) reconcileNormal(ctx context.Context, cluster *clu
if clusterVApp == nil || clusterVApp.VApp == nil {
return ctrl.Result{}, errors.Wrapf(err, "found nil value for VApp [%s]", vcdCluster.Name)
}
if !strings.HasPrefix(vcdCluster.Status.InfraId, NoRdePrefix) {
if err := r.reconcileRDE(ctx, cluster, vcdCluster, workloadVCDClient, clusterVApp.VApp.ID, true); err != nil {
log.Error(err, "failed to add VApp ID to RDE", "rdeID", infraID, "vappID", clusterVApp.VApp.ID)
return ctrl.Result{}, errors.Wrapf(err, "failed to update RDE [%s] with VApp ID [%s]: [%v]", vcdCluster.Status.InfraId, clusterVApp.VApp.ID, err)
}
log.Info("successfully updated external ID of RDE with VApp ID", "infraID", infraID, "vAppID", clusterVApp.VApp.ID)
}

if metadataMap != nil && len(metadataMap) > 0 && !vcdCluster.Status.VAppMetadataUpdated {
if err := vdcManager.AddMetadataToVApp(vcdCluster.Name, metadataMap); err != nil {
return ctrl.Result{}, fmt.Errorf("unable to add metadata [%s] to vApp [%s]: [%v]", metadataMap, vcdCluster.Name, err)
Expand Down
14 changes: 12 additions & 2 deletions examples/rde1_1_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,18 @@
"createdByVersion": "1.1.0",
"capvcdVersion": "ABCD",
"vcdProperties": {
"orgName": "ABCDEFGHIJKLMNOPQRSTUVWXYZAB",
"virtualDataCenterName": "ABCDEFGHIJKLMNOPQRSTUVWX",
"vcdOrg": [
{
"name": "ABCDEFGHIJKLMNOPQRSTUVWXYZAB",
"id": "274c6240-3304-11ed-a261-0242ac120002"
}
],
"orgVdc": [
{
"name": "ABCDEFGHIJKLMNOPQRSTUVWXYZAB",
"id": "274c6240-3304-11ed-a261-0242ac120002"
}
],
"ovdcNetworkName": "ABCDEFGHIJKLMNOPQ",
"site": "ABCDEFGHIJKLMNOPQRSTUVWX"
},
Expand Down
9 changes: 7 additions & 2 deletions pkg/capisdk/defined_entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (capvcdRdeManager *CapvcdRdeManager) SetIsManagementClusterInRDE(ctx contex
}
capvcdStatusPatch := make(map[string]interface{})
capvcdStatusPatch["UsedAsManagementCluster"] = true
_, err := capvcdRdeManager.PatchRDE(ctx, nil, nil, capvcdStatusPatch, managementClusterRDEId)
_, err := capvcdRdeManager.PatchRDE(ctx, nil, nil, capvcdStatusPatch, managementClusterRDEId, "", false)
if err != nil {
return fmt.Errorf("failed to set isManagementCluster flag for management cluster with RDE ID [%s]: [%v]",
managementClusterRDEId, err)
Expand All @@ -150,7 +150,8 @@ func (capvcdRdeManager *CapvcdRdeManager) SetIsManagementClusterInRDE(ctx contex
// specPatch["CapiYaml"] = updated-yaml
// metadataPatch["Name"] = updated-name
// capvcdStatusPatch["Version"] = updated-version
func (capvcdRdeManager *CapvcdRdeManager) PatchRDE(ctx context.Context, specPatch, metadataPatch, capvcdStatusPatch map[string]interface{}, rdeID string) (rde *swagger.DefinedEntity, err error) {
func (capvcdRdeManager *CapvcdRdeManager) PatchRDE(ctx context.Context, specPatch, metadataPatch,
capvcdStatusPatch map[string]interface{}, rdeID string, externalID string, updateExternalID bool) (rde *swagger.DefinedEntity, err error) {
defer func() {
// recover from panic if panic occurs because of
// 1. calling Set() on a zero value
Expand Down Expand Up @@ -211,6 +212,10 @@ func (capvcdRdeManager *CapvcdRdeManager) PatchRDE(ctx context.Context, specPatc
return nil, fmt.Errorf("failed to patch capvcd status in the CAPVCD entity: [%v]", err)
}
}
if updateExternalID {
klog.V(4).Infof("setting externalID as [%s] in RDE [%s]", externalID, rdeID)
rde.ExternalId = externalID
}

// update the defined entity
rde, resp, err = client.APIClient.DefinedEntityApi.UpdateDefinedEntity(ctx, rde, etag, rdeID, nil)
Expand Down
14 changes: 12 additions & 2 deletions pkg/vcdtypes/rde_type_1_1_0/types_1_1_0.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,21 @@ type Services struct {
CidrBlocks []string `json:"cidrBlocks,omitempty"`
}

type Ovdc struct {
Name string `json:"name,omitempty"`
ID string `json:"id,omitempty"`
}

type Org struct {
Name string `json:"name,omitempty"`
ID string `json:"id,omitempty"`
}

type VCDProperties struct {
Site string `json:"site,omitempty"`
Org string `json:"orgName,omitempty"`
Vdc string `json:"virtualDataCenterName,omitempty"`
OvdcNetwork string `json:"ovdcNetworkName,omitempty"`
Ovdc []Ovdc `json:"orgVdc,omitempty"`
Org []Org `json:"vcdOrg,omitempty"`
}

type ApiEndpoints struct {
Expand Down
29 changes: 24 additions & 5 deletions schema/schema_1_1_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,36 @@
"vcdProperties": {
"type": "object",
"properties": {
"orgName": {
"type": "string"
},
"virtualDataCenterName": {
"type": "string"
"vcdOrg": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
}
}
},
"ovdcNetworkName": {
"type": "string"
},
"site": {
"type": "string"
},
"orgVdc": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
}
}
}
}
}
},
Expand Down

0 comments on commit d68b804

Please sign in to comment.