@@ -78,7 +78,8 @@ const (
78
78
reasonPopulateOperationStartSuccess = "PopulateOperationStartSuccess"
79
79
reasonPopulateOperationFailed = "PopulateOperationFailed"
80
80
reasonPopulateOperationFinished = "PopulateOperationFinished"
81
- reasonPVCCreationError = "PopulatorPVCPrimeCreationError"
81
+ reasonPVCPrimeCreationError = "PopulatorPVCPrimeCreationError"
82
+ reasonPVCPrimeMutatorError = "reasonPVCPrimeMutatorError"
82
83
reasonWaitForDataPopulationFinished = "PopulatorWaitForDataPopulationFinished"
83
84
reasonStorageClassCreationError = "PopulatorStorageClassCreationError"
84
85
reasonDataSourceNotFound = "PopulatorDataSourceNotFound"
@@ -116,6 +117,7 @@ type controller struct {
116
117
referenceGrantSynced cache.InformerSynced
117
118
podConfig * PodConfig
118
119
providerFunctionConfig * ProviderFunctionConfig
120
+ mutatorConfig * MutatorConfig
119
121
crossNamespace bool
120
122
providerMetricManager * ProviderMetricManager
121
123
}
@@ -140,6 +142,9 @@ type VolumePopulatorConfig struct {
140
142
// ProviderFunctionConfig is the configuration for invoking provider functions. Either PodConfig or ProviderFunctionConfig should
141
143
// be specified. PodConfig and ProviderFunctionConfig can't be provided at the same time
142
144
ProviderFunctionConfig * ProviderFunctionConfig
145
+ // MutatorConfig is the configuration for invoking mutator functions. You can specify your own mutator functions to modify the
146
+ // Kubernetes resources used for volume population
147
+ MutatorConfig * MutatorConfig
143
148
// ProviderMetricManager is the manager for provider specific metric handling
144
149
ProviderMetricManager * ProviderMetricManager
145
150
// CrossNamespace indicates if the populator supports data sources located in namespaces different than the PVC's namespace.
@@ -189,6 +194,19 @@ type PopulatorParams struct {
189
194
Recorder record.EventRecorder
190
195
}
191
196
197
+ type MutatorConfig struct {
198
+ // PvcPrimeMutator is the mutator function for pvcPrime. The function gets called to modify the PVC object before pvcPrime gets created.
199
+ PvcPrimeMutator func (PvcPrimeMutatorParams ) (* corev1.PersistentVolumeClaim , error )
200
+ }
201
+
202
+ // PvcPrimeMutatorParams includes the parameters passing to the PvcPrimeMutator function
203
+ type PvcPrimeMutatorParams struct {
204
+ // PvcPrime is the temporary PVC created by volume populator
205
+ PvcPrime * corev1.PersistentVolumeClaim
206
+ // StorageClass is the original StorageClass Pvc refer to
207
+ StorageClass * storagev1.StorageClass
208
+ }
209
+
192
210
func RunController (masterURL , kubeconfig , imageName , httpEndpoint , metricsPath , namespace , prefix string ,
193
211
gk schema.GroupKind , gvr schema.GroupVersionResource , mountPath , devicePath string ,
194
212
populatorArgs func (bool , * unstructured.Unstructured ) ([]string , error ),
@@ -292,6 +310,7 @@ func RunControllerWithConfig(vpcfg VolumePopulatorConfig) {
292
310
referenceGrantSynced : referenceGrants .Informer ().HasSynced ,
293
311
podConfig : vpcfg .PodConfig ,
294
312
providerFunctionConfig : vpcfg .ProviderFunctionConfig ,
313
+ mutatorConfig : vpcfg .MutatorConfig ,
295
314
crossNamespace : vpcfg .CrossNamespace ,
296
315
providerMetricManager : vpcfg .ProviderMetricManager ,
297
316
}
@@ -701,9 +720,24 @@ func (c *controller) syncPvc(ctx context.Context, key, pvcNamespace, pvcName str
701
720
annSelectedNode : nodeName ,
702
721
}
703
722
}
723
+ if c .mutatorConfig != nil && c .mutatorConfig .PvcPrimeMutator != nil {
724
+ mp := PvcPrimeMutatorParams {
725
+ PvcPrime : pvcPrime ,
726
+ StorageClass : storageClass ,
727
+ }
728
+ pvcPrime , err = c .mutatorConfig .PvcPrimeMutator (mp )
729
+ if err != nil {
730
+ c .recorder .Eventf (pvc , corev1 .EventTypeWarning , reasonPVCPrimeMutatorError , "Failed to mutate populator pvcPrime: %s" , err )
731
+ return err
732
+ }
733
+ if pvcPrime == nil {
734
+ c .recorder .Eventf (pvc , corev1 .EventTypeWarning , reasonPVCPrimeMutatorError , "pvcPrime must not be nil" )
735
+ return fmt .Errorf ("pvcPrime must not be nil" )
736
+ }
737
+ }
704
738
pvcPrime , err = c .kubeClient .CoreV1 ().PersistentVolumeClaims (c .populatorNamespace ).Create (ctx , pvcPrime , metav1.CreateOptions {})
705
739
if err != nil {
706
- c .recorder .Eventf (pvc , corev1 .EventTypeWarning , reasonPVCCreationError , "Failed to create populator PVC prime : %s" , err )
740
+ c .recorder .Eventf (pvc , corev1 .EventTypeWarning , reasonPVCPrimeCreationError , "Failed to create populator pvcPrime : %s" , err )
707
741
return err
708
742
}
709
743
}
@@ -734,7 +768,7 @@ func (c *controller) syncPvc(ctx context.Context, key, pvcNamespace, pvcName str
734
768
if c .providerFunctionConfig .PopulateFn != nil {
735
769
736
770
if "" == pvcPrime .Spec .VolumeName {
737
- // We'll get called again later when the pvc prime gets bounded
771
+ // We'll get called again later when the pvcPrime gets bounded
738
772
return nil
739
773
}
740
774
pv , err := params .KubeClient .CoreV1 ().PersistentVolumes ().Get (ctx , pvcPrime .Spec .VolumeName , metav1.GetOptions {})
0 commit comments