Skip to content

Commit

Permalink
Generate events on PV when volume cannot be created on any of the VCs
Browse files Browse the repository at this point in the history
  • Loading branch information
skogta committed Dec 22, 2023
1 parent f545cf9 commit d563c11
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
5 changes: 5 additions & 0 deletions pkg/syncer/metadatasyncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2253,6 +2253,7 @@ func csiPVUpdated(ctx context.Context, newPv *v1.PersistentVolume, oldPv *v1.Per
if err != nil {
log.Errorf("PVUpdated: Failed to get VC host and volume manager for multi VC setup. "+
"Error occurred: %+v", err)
generateEventOnPv(ctx, oldPv, staticVolumeProvisioningFailure, "Failed to identify VC for volume.")
return
}
} else {
Expand All @@ -2279,6 +2280,7 @@ func csiPVUpdated(ctx context.Context, newPv *v1.PersistentVolume, oldPv *v1.Per
} else {
// Failed to create static PV
log.Errorf("PVUpdated: Failed to create static file volume %q. Error: %+v", newPv.Name, err)
generateEventOnPv(ctx, oldPv, staticVolumeProvisioningFailure, "Failed to create volume on any of the VCs")
return
}
return
Expand All @@ -2292,6 +2294,7 @@ func csiPVUpdated(ctx context.Context, newPv *v1.PersistentVolume, oldPv *v1.Per
if err != nil {
log.Errorf("PVUpdated: Failed to get VC host and volume manager for single VC setup. "+
"Error occoured: %+v", err)
generateEventOnPv(ctx, oldPv, staticVolumeProvisioningFailure, "Failed to identify VC for volume")
return
}
}
Expand Down Expand Up @@ -2321,6 +2324,8 @@ func csiPVUpdated(ctx context.Context, newPv *v1.PersistentVolume, oldPv *v1.Per
"Calling CreateVolume with BackingID to mark volume as Container Volume.", oldPv.Spec.CSI.VolumeHandle)
// Call CreateVolume for Static Volume Provisioning.
_ = createCnsVolume(ctx, oldPv, metadataSyncer, cnsVolumeMgr, volumeType, vcHost, metadataList, volumeHandle)
errMsg := fmt.Sprintf("Failed to create volume on VC %s", vcHost)
generateEventOnPv(ctx, oldPv, staticVolumeProvisioningFailure, errMsg)
return
} else if queryResult.Volumes[0].VolumeId.Id == oldPv.Spec.CSI.VolumeHandle {
log.Infof("PVUpdated: Verified volume: %q is already marked as container volume in CNS.",
Expand Down
37 changes: 35 additions & 2 deletions pkg/syncer/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
apitypes "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"
cnsconfig "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/config"
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common/commonco"
Expand All @@ -20,6 +22,8 @@ import (
cnstypes "github.com/vmware/govmomi/cns/types"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
k8s "sigs.k8s.io/vsphere-csi-driver/v3/pkg/kubernetes"

storagepolicyusagev1alpha1 "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator/storagepolicy/v1alpha1"
"sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/migration"
Expand All @@ -31,6 +35,15 @@ import (
csitypes "sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/types"
)

const (
// These are the values required for geenrating events on a K8s object

// Syncer component name
syncerComponent = "VSphere CSI Syncer"
// reason for PV creation failure when static volume provioining fails
staticVolumeProvisioningFailure = "static volume provisioning failed"
)

// getPVsInBoundAvailableOrReleased return PVs in Bound, Available or Released
// state.
func getPVsInBoundAvailableOrReleased(ctx context.Context,
Expand Down Expand Up @@ -482,6 +495,11 @@ func getVcHostFromTopologySegments(ctx context.Context, topologySegments []map[s
log := logger.GetLogger(ctx)
var vcHost string

if len(topologySegments) == 0 {
return "", logger.LogNewErrorf(log,
"Invalid volume %s as it does not have node affinity rules", volumeName)
}

for _, topology := range topologySegments {

vc, err := getVCForTopologySegments(ctx, topology)
Expand Down Expand Up @@ -618,9 +636,9 @@ func getPVsInBoundAvailableOrReleasedForVc(ctx context.Context, metadataSyncer *
topologySegments := getTopologySegmentsFromNodeAffinityRules(ctx, volume)
vCenter, err := getVcHostFromTopologySegments(ctx, topologySegments, volume.Name)
if err != nil {
return nil, logger.LogNewErrorf(log,
"Failed to find which VC volume %+v belongs to from ndeAffinityrules",
log.Debugf("Failed to find which VC volume %+v belongs to from nodeAffinityRules",
volume.Spec.CSI.VolumeHandle)
continue
}

if vCenter == vc {
Expand Down Expand Up @@ -669,6 +687,21 @@ func createVolumeOnMultiVc(ctx context.Context, pv *v1.PersistentVolume,
"Failed to create volume %s on any of the VCs", volumeHandle)
}

func generateEventOnPv(ctx context.Context, pv *v1.PersistentVolume, failureReason string, errorMsg string) {
log := logger.GetLogger(ctx)

eventBroadcaster := record.NewBroadcaster()
k8sClient, err := k8s.NewClient(ctx)
if err != nil {
log.Errorf("Failed to create k8s client. Err: %v", err)
return
}

eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: k8sClient.CoreV1().Events("")})
eventRecorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: syncerComponent})
eventRecorder.Event(pv, v1.EventTypeWarning, failureReason, errorMsg)
}

func createCnsVolume(ctx context.Context, pv *v1.PersistentVolume,
metadataSyncer *metadataSyncInformer, cnsVolumeMgr volumes.Manager, volumeType string,
vcHost string, metadataList []cnstypes.BaseCnsEntityMetadata, volumeHandle string) error {
Expand Down

0 comments on commit d563c11

Please sign in to comment.