github.com/openebs/api@v1.12.0/pkg/apis/cstor/v1/cstorvolumebuilder.go (about)

     1  /*
     2  Copyright 2020 The OpenEBS Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may ocvtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required cvy applicacvle law or agreed to in writing, software
    11  districvuted under the License is districvuted on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v1
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	"github.com/openebs/api/pkg/apis/types"
    24  	"github.com/openebs/api/pkg/util"
    25  	"k8s.io/apimachinery/pkg/api/resource"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/klog"
    28  )
    29  
    30  const (
    31  
    32  	//CStorNodeBase nodeBase for cstor volume
    33  	CStorNodeBase string = "iqn.2016-09.com.openebs.cstor"
    34  
    35  	// TargetPort is port for cstor volume
    36  	TargetPort string = "3260"
    37  
    38  	// CStorVolumeReplicaFinalizer is the name of finalizer on CStorVolumeConfig
    39  	CStorVolumeReplicaFinalizer = "cstorvolumereplica.openebs.io/finalizer"
    40  )
    41  
    42  // NewCStorVolumeConfig returns new instance of CStorVolumeConfig
    43  func NewCStorVolumeConfig() *CStorVolumeConfig {
    44  	return &CStorVolumeConfig{}
    45  }
    46  
    47  // WithName sets the Name field of CVC with provided value.
    48  func (cvc *CStorVolumeConfig) WithName(name string) *CStorVolumeConfig {
    49  	cvc.Name = name
    50  	return cvc
    51  }
    52  
    53  // WithNamespace sets the Namespace field of CVC provided arguments
    54  func (cvc *CStorVolumeConfig) WithNamespace(namespace string) *CStorVolumeConfig {
    55  	cvc.Namespace = namespace
    56  	return cvc
    57  }
    58  
    59  // WithAnnotationsNew sets the Annotations field of CVC with provided arguments
    60  func (cvc *CStorVolumeConfig) WithAnnotationsNew(annotations map[string]string) *CStorVolumeConfig {
    61  	cvc.Annotations = make(map[string]string)
    62  	for key, value := range annotations {
    63  		cvc.Annotations[key] = value
    64  	}
    65  	return cvc
    66  }
    67  
    68  // WithAnnotations appends or overwrites existing Annotations
    69  // values of CVC with provided arguments
    70  func (cvc *CStorVolumeConfig) WithAnnotations(annotations map[string]string) *CStorVolumeConfig {
    71  
    72  	if cvc.Annotations == nil {
    73  		return cvc.WithAnnotationsNew(annotations)
    74  	}
    75  	for key, value := range annotations {
    76  		cvc.Annotations[key] = value
    77  	}
    78  	return cvc
    79  }
    80  
    81  // WithLabelsNew sets the Lacvels field of CVC with provided arguments
    82  func (cvc *CStorVolumeConfig) WithLabelsNew(labels map[string]string) *CStorVolumeConfig {
    83  	cvc.Labels = make(map[string]string)
    84  	for key, value := range labels {
    85  		cvc.Labels[key] = value
    86  	}
    87  	return cvc
    88  }
    89  
    90  // WithLabels appends or overwrites existing Lacvels
    91  // values of CVC with provided arguments
    92  func (cvc *CStorVolumeConfig) WithLabels(labels map[string]string) *CStorVolumeConfig {
    93  	if cvc.Labels == nil {
    94  		return cvc.WithLabelsNew(labels)
    95  	}
    96  	for key, value := range labels {
    97  		cvc.Labels[key] = value
    98  	}
    99  	return cvc
   100  }
   101  
   102  // WithFinalizer sets the finalizer field in the CVC
   103  func (cvc *CStorVolumeConfig) WithFinalizer(finalizers ...string) *CStorVolumeConfig {
   104  	cvc.Finalizers = append(cvc.Finalizers, finalizers...)
   105  	return cvc
   106  }
   107  
   108  // WithOwnerReference sets the OwnerReference field in CVC with required
   109  //fields
   110  func (cvc *CStorVolumeConfig) WithOwnerReference(reference metav1.OwnerReference) *CStorVolumeConfig {
   111  	cvc.OwnerReferences = append(cvc.OwnerReferences, reference)
   112  	return cvc
   113  }
   114  
   115  // WithNewVersion sets the current and desired version field of
   116  // CVC with provided arguments
   117  func (cvc *CStorVolumeConfig) WithNewVersion(version string) *CStorVolumeConfig {
   118  	cvc.VersionDetails.Status.Current = version
   119  	cvc.VersionDetails.Desired = version
   120  	return cvc
   121  }
   122  
   123  // WithDependentsUpgraded sets the field to true for new CVC
   124  func (cvc *CStorVolumeConfig) WithDependentsUpgraded() *CStorVolumeConfig {
   125  	cvc.VersionDetails.Status.DependentsUpgraded = true
   126  	return cvc
   127  }
   128  
   129  // HasFinalizer returns true if the provided finalizer is present on the ocvject.
   130  func (cvc *CStorVolumeConfig) HasFinalizer(finalizer string) bool {
   131  	finalizersList := cvc.GetFinalizers()
   132  	return util.ContainsString(finalizersList, finalizer)
   133  }
   134  
   135  // RemoveFinalizer removes the given finalizer from the ocvject.
   136  func (cvc *CStorVolumeConfig) RemoveFinalizer(finalizer string) {
   137  	cvc.Finalizers = util.RemoveString(cvc.Finalizers, finalizer)
   138  }
   139  
   140  // GetDesiredReplicaPoolNames returns list of desired pool names
   141  func GetDesiredReplicaPoolNames(cvc *CStorVolumeConfig) []string {
   142  	poolNames := []string{}
   143  	for _, poolInfo := range cvc.Spec.Policy.ReplicaPoolInfo {
   144  		poolNames = append(poolNames, poolInfo.PoolName)
   145  	}
   146  	return poolNames
   147  }
   148  
   149  // IsScaleDownInProgress return true if length of status replica details is
   150  // greater than length of spec replica details
   151  func IsScaleDownInProgress(cv *CStorVolume) bool {
   152  	return len(cv.Status.ReplicaDetails.KnownReplicas) >
   153  		len(cv.Spec.ReplicaDetails.KnownReplicas)
   154  }
   155  
   156  // **************************************************************************
   157  //
   158  //                                CSTOR VOLUMES
   159  //
   160  //
   161  // **************************************************************************
   162  
   163  // NewCStorVolume returns new instance of CStorVolume
   164  func NewCStorVolume() *CStorVolume {
   165  	return &CStorVolume{}
   166  }
   167  
   168  // NewCStorVolumeObj returns a new instance of cstorvolume
   169  func NewCStorVolumeObj(obj *CStorVolume) *CStorVolume {
   170  	return obj
   171  }
   172  
   173  // WithName sets the Name field of CVC with provided value.
   174  func (cv *CStorVolume) WithName(name string) *CStorVolume {
   175  	cv.Name = name
   176  	return cv
   177  }
   178  
   179  // WithNamespace sets the Namespace field of CVC provided arguments
   180  func (cv *CStorVolume) WithNamespace(namespace string) *CStorVolume {
   181  	cv.Namespace = namespace
   182  	return cv
   183  }
   184  
   185  // WithAnnotationsNew sets the Annotations field of CVC with provided arguments
   186  func (cv *CStorVolume) WithAnnotationsNew(annotations map[string]string) *CStorVolume {
   187  	cv.Annotations = make(map[string]string)
   188  	for key, value := range annotations {
   189  		cv.Annotations[key] = value
   190  	}
   191  	return cv
   192  }
   193  
   194  // WithAnnotations appends or overwrites existing Annotations
   195  // values of CV with provided arguments
   196  func (cv *CStorVolume) WithAnnotations(annotations map[string]string) *CStorVolume {
   197  
   198  	if cv.Annotations == nil {
   199  		return cv.WithAnnotationsNew(annotations)
   200  	}
   201  	for key, value := range annotations {
   202  		cv.Annotations[key] = value
   203  	}
   204  	return cv
   205  }
   206  
   207  // WithLabelsNew sets the Lacvels field of CV with provided arguments
   208  func (cv *CStorVolume) WithLabelsNew(labels map[string]string) *CStorVolume {
   209  	cv.Labels = make(map[string]string)
   210  	for key, value := range labels {
   211  		cv.Labels[key] = value
   212  	}
   213  	return cv
   214  }
   215  
   216  // WithLabels appends or overwrites existing Lacvels
   217  // values of CVC with provided arguments
   218  func (cv *CStorVolume) WithLabels(labels map[string]string) *CStorVolume {
   219  	if cv.Labels == nil {
   220  		return cv.WithLabelsNew(labels)
   221  	}
   222  	for key, value := range labels {
   223  		cv.Labels[key] = value
   224  	}
   225  	return cv
   226  }
   227  
   228  // WithFinalizers sets the finalizer field in the CV
   229  func (cv *CStorVolume) WithFinalizers(finalizers ...string) *CStorVolume {
   230  	cv.Finalizers = append(cv.Finalizers, finalizers...)
   231  	return cv
   232  }
   233  
   234  // WithOwnerReference sets the OwnerReference field in CV with required
   235  //fields
   236  func (cv *CStorVolume) WithOwnerReference(reference []metav1.OwnerReference) *CStorVolume {
   237  	cv.OwnerReferences = append(cv.OwnerReferences, reference...)
   238  	return cv
   239  }
   240  
   241  // WithTargetIP sets the target IP address field of
   242  // CStorVolume with provided arguments
   243  func (cv *CStorVolume) WithTargetIP(targetip string) *CStorVolume {
   244  	cv.Spec.TargetIP = targetip
   245  	return cv
   246  }
   247  
   248  // WithCapacity sets the Capacity field of CStorVolume with provided arguments
   249  func (cv *CStorVolume) WithCapacity(capacity string) *CStorVolume {
   250  	capacityQnt, _ := resource.ParseQuantity(capacity)
   251  	cv.Spec.Capacity = capacityQnt
   252  	return cv
   253  }
   254  
   255  // WithCStorIQN sets the iqn field of CStorVolume with provided arguments
   256  func (cv *CStorVolume) WithCStorIQN(name string) *CStorVolume {
   257  	iqn := CStorNodeBase + ":" + name
   258  	cv.Spec.Iqn = iqn
   259  	return cv
   260  }
   261  
   262  // WithTargetPortal sets the TargetPortal field of
   263  // CStorVolume with provided arguments
   264  func (cv *CStorVolume) WithTargetPortal(targetportal string) *CStorVolume {
   265  	cv.Spec.TargetPortal = targetportal
   266  	return cv
   267  }
   268  
   269  // WithTargetPort sets the TargetPort field of
   270  // CStorVolume with provided arguments
   271  func (cv *CStorVolume) WithTargetPort(targetport string) *CStorVolume {
   272  	cv.Spec.TargetPort = targetport
   273  	return cv
   274  }
   275  
   276  // WithReplicationFactor sets the ReplicationFactor field of
   277  // CStorVolume with provided arguments
   278  func (cv *CStorVolume) WithReplicationFactor(replicationfactor int) *CStorVolume {
   279  	cv.Spec.ReplicationFactor = replicationfactor
   280  	return cv
   281  }
   282  
   283  // WithDesiredReplicationFactor sets the DesiredReplicationFactor field of
   284  // CStorVolume with provided arguments
   285  func (cv *CStorVolume) WithDesiredReplicationFactor(desiredRF int) *CStorVolume {
   286  	cv.Spec.DesiredReplicationFactor = desiredRF
   287  	return cv
   288  }
   289  
   290  // WithConsistencyFactor sets the ConsistencyFactor field of
   291  // CStorVolume with provided arguments
   292  func (cv *CStorVolume) WithConsistencyFactor(consistencyfactor int) *CStorVolume {
   293  	cv.Spec.ConsistencyFactor = consistencyfactor
   294  	return cv
   295  }
   296  
   297  // WithNewVersion sets the current and desired version field of
   298  // CV with provided arguments
   299  func (cv *CStorVolume) WithNewVersion(version string) *CStorVolume {
   300  	cv.VersionDetails.Status.Current = version
   301  	cv.VersionDetails.Desired = version
   302  	return cv
   303  }
   304  
   305  // WithDependentsUpgraded sets the field to true for new CV
   306  func (cv *CStorVolume) WithDependentsUpgraded() *CStorVolume {
   307  	cv.VersionDetails.Status.DependentsUpgraded = true
   308  	return cv
   309  }
   310  
   311  // HasFinalizer returns true if the provided finalizer is present on the ocvject.
   312  func (cv *CStorVolume) HasFinalizer(finalizer string) bool {
   313  	finalizersList := cv.GetFinalizers()
   314  	return util.ContainsString(finalizersList, finalizer)
   315  }
   316  
   317  // RemoveFinalizer removes the given finalizer from the ocvject.
   318  func (cv *CStorVolume) RemoveFinalizer(finalizer string) {
   319  	cv.Finalizers = util.RemoveString(cv.Finalizers, finalizer)
   320  }
   321  
   322  // IsResizePending return true if resize is in progress
   323  func (cv *CStorVolume) IsResizePending() bool {
   324  	curCapacity := cv.Status.Capacity
   325  	desiredCapacity := cv.Spec.Capacity
   326  	// Cmp returns 0 if the curCapacity is equal to desiredCapacity,
   327  	// -1 if the curCapacity is less than desiredCapacity, or 1 if the
   328  	// curCapacity is greater than desiredCapacity.
   329  	return curCapacity.Cmp(desiredCapacity) == -1
   330  }
   331  
   332  // IsDRFPending return true if drf update is required else false
   333  // Steps to verify whether drf is required
   334  // 1. Read DesiredReplicationFactor configurations from istgt conf file
   335  // 2. Compare the value with spec.DesiredReplicationFactor and return result
   336  func (cv *CStorVolume) IsDRFPending() bool {
   337  	fileOperator := util.RealFileOperator{}
   338  	types.ConfFileMutex.Lock()
   339  	//If it has proper config then we will get --> "  DesiredReplicationFactor 3"
   340  	i, gotConfig, err := fileOperator.GetLineDetails(types.IstgtConfPath, types.DesiredReplicationFactorKey)
   341  	types.ConfFileMutex.Unlock()
   342  	if err != nil || i == -1 {
   343  		klog.Infof("failed to get %s config details error: %v",
   344  			types.DesiredReplicationFactorKey,
   345  			err,
   346  		)
   347  		return false
   348  	}
   349  	drfStringValue := fmt.Sprintf(" %d", cv.Spec.DesiredReplicationFactor)
   350  	// gotConfig will have "  DesiredReplicationFactor  3" and we will extract
   351  	// numeric character from output
   352  	if !strings.HasSuffix(gotConfig, drfStringValue) {
   353  		return true
   354  	}
   355  	// reconciliation check for replica scaledown scenarion
   356  	return (len(cv.Spec.ReplicaDetails.KnownReplicas) <
   357  		len(cv.Status.ReplicaDetails.KnownReplicas))
   358  }
   359  
   360  // GetCVCondition returns corresponding cstorvolume condition based argument passed
   361  func (cv *CStorVolume) GetCVCondition(
   362  	condType CStorVolumeConditionType) CStorVolumeCondition {
   363  	for _, cond := range cv.Status.Conditions {
   364  		if condType == cond.Type {
   365  			return cond
   366  		}
   367  	}
   368  	return CStorVolumeCondition{}
   369  }
   370  
   371  // IsConditionPresent returns true if condition is available
   372  func (cv *CStorVolume) IsConditionPresent(condType CStorVolumeConditionType) bool {
   373  	for _, cond := range cv.Status.Conditions {
   374  		if condType == cond.Type {
   375  			return true
   376  		}
   377  	}
   378  	return false
   379  }
   380  
   381  // AreSpecReplicasHealthy return true if all the spec replicas are in Healthy
   382  // state else return false
   383  func (cv *CStorVolume) AreSpecReplicasHealthy(volStatus *CVStatus) bool {
   384  	var isReplicaExist bool
   385  	var replicaInfo ReplicaStatus
   386  	for _, replicaValue := range cv.Spec.ReplicaDetails.KnownReplicas {
   387  		isReplicaExist = false
   388  		for _, replicaInfo = range volStatus.ReplicaStatuses {
   389  			if replicaInfo.ID == replicaValue {
   390  				isReplicaExist = true
   391  				break
   392  			}
   393  		}
   394  		if (isReplicaExist && replicaInfo.Mode != "Healthy") || !isReplicaExist {
   395  			return false
   396  		}
   397  	}
   398  	return true
   399  }
   400  
   401  // GetRemovingReplicaID return replicaID that present in status but not in spec
   402  func (cv *CStorVolume) GetRemovingReplicaID() string {
   403  	for repID := range cv.Status.ReplicaDetails.KnownReplicas {
   404  		// If known replica is not exist in spec but if it exist in status then
   405  		// user/operator selected that replica for removal
   406  		if _, isReplicaExist :=
   407  			cv.Spec.ReplicaDetails.KnownReplicas[repID]; !isReplicaExist {
   408  			return string(repID)
   409  		}
   410  	}
   411  	return ""
   412  }
   413  
   414  // BuildScaleDownConfigData build data based on replica that needs to remove
   415  func (cv *CStorVolume) BuildScaleDownConfigData(repID string) map[string]string {
   416  	configData := map[string]string{}
   417  	newReplicationFactor := cv.Spec.DesiredReplicationFactor
   418  	newConsistencyFactor := (newReplicationFactor / 2) + 1
   419  	key := fmt.Sprintf("  ReplicationFactor")
   420  	value := fmt.Sprintf("  ReplicationFactor %d", newReplicationFactor)
   421  	configData[key] = value
   422  	key = fmt.Sprintf("  ConsistencyFactor")
   423  	value = fmt.Sprintf("  ConsistencyFactor %d", newConsistencyFactor)
   424  	configData[key] = value
   425  	key = fmt.Sprintf("  DesiredReplicationFactor")
   426  	value = fmt.Sprintf("  DesiredReplicationFactor %d",
   427  		cv.Spec.DesiredReplicationFactor)
   428  	configData[key] = value
   429  	key = fmt.Sprintf("  Replica %s", repID)
   430  	value = fmt.Sprintf("")
   431  	configData[key] = value
   432  	return configData
   433  }
   434  
   435  // Conditions enables building CRUD operations on cstorvolume conditions
   436  type Conditions []CStorVolumeCondition
   437  
   438  // AddCondition appends the new condition to existing conditions
   439  func (c Conditions) AddCondition(cond CStorVolumeCondition) []CStorVolumeCondition {
   440  	c = append(c, cond)
   441  	return c
   442  }
   443  
   444  // UpdateCondition updates the condition if it is present in Conditions
   445  func (c Conditions) UpdateCondition(cond CStorVolumeCondition) []CStorVolumeCondition {
   446  	for i, condObj := range c {
   447  		if condObj.Type == cond.Type {
   448  			c[i] = cond
   449  		}
   450  	}
   451  	return c
   452  }
   453  
   454  // DeleteCondition deletes the condition from conditions
   455  func (c Conditions) DeleteCondition(cond CStorVolumeCondition) []CStorVolumeCondition {
   456  	newConditions := []CStorVolumeCondition{}
   457  	for _, condObj := range c {
   458  		if condObj.Type != cond.Type {
   459  			newConditions = append(newConditions, condObj)
   460  		}
   461  	}
   462  	return newConditions
   463  }
   464  
   465  // GetResizeCondition will return resize condtion related to
   466  // cstorvolume condtions
   467  func GetResizeCondition() CStorVolumeCondition {
   468  	resizeConditions := CStorVolumeCondition{
   469  		Type:               CStorVolumeResizing,
   470  		Status:             ConditionInProgress,
   471  		LastProbeTime:      metav1.Now(),
   472  		LastTransitionTime: metav1.Now(),
   473  		Reason:             "Resizing",
   474  		Message:            "Triggered resize by changing capacity in spec",
   475  	}
   476  	return resizeConditions
   477  }
   478  
   479  // ****************************************************************************
   480  //
   481  //                       Version Details
   482  //
   483  //
   484  // ****************************************************************************
   485  
   486  // SetErrorStatus sets the message and reason for the error
   487  func (vs *VersionStatus) SetErrorStatus(msg string, err error) {
   488  	vs.Message = msg
   489  	vs.Reason = err.Error()
   490  	vs.LastUpdateTime = metav1.Now()
   491  }
   492  
   493  // SetInProgressStatus sets the state as ReconcileInProgress
   494  func (vs *VersionStatus) SetInProgressStatus() {
   495  	vs.State = ReconcileInProgress
   496  	vs.LastUpdateTime = metav1.Now()
   497  }
   498  
   499  // SetSuccessStatus resets the message and reason and sets the state as
   500  // Reconciled
   501  func (vd *VersionDetails) SetSuccessStatus() {
   502  	vd.Status.Current = vd.Desired
   503  	vd.Status.Message = ""
   504  	vd.Status.Reason = ""
   505  	vd.Status.State = ReconcileComplete
   506  	vd.Status.LastUpdateTime = metav1.Now()
   507  }
   508  
   509  // **************************************************************************
   510  //
   511  //                                CSTOR VOLUMES REPLICA
   512  //
   513  //
   514  // **************************************************************************
   515  
   516  // NewCStorVolumeReplica returns new instance of CStorVolumeReplica
   517  func NewCStorVolumeReplica() *CStorVolumeReplica {
   518  	return &CStorVolumeReplica{}
   519  }
   520  
   521  // WithName sets the Name field of CVR with provided value.
   522  func (cvr *CStorVolumeReplica) WithName(name string) *CStorVolumeReplica {
   523  	cvr.Name = name
   524  	return cvr
   525  }
   526  
   527  // WithNamespace sets the Namespace field of CVC provided arguments
   528  func (cvr *CStorVolumeReplica) WithNamespace(namespace string) *CStorVolumeReplica {
   529  	cvr.Namespace = namespace
   530  	return cvr
   531  }
   532  
   533  // WithAnnotationsNew sets the Annotations field of CVC with provided arguments
   534  func (cvr *CStorVolumeReplica) WithAnnotationsNew(annotations map[string]string) *CStorVolumeReplica {
   535  	cvr.Annotations = make(map[string]string)
   536  	for key, value := range annotations {
   537  		cvr.Annotations[key] = value
   538  	}
   539  	return cvr
   540  }
   541  
   542  // WithAnnotations appends or overwrites existing Annotations
   543  // values of CV with provided arguments
   544  func (cvr *CStorVolumeReplica) WithAnnotations(annotations map[string]string) *CStorVolumeReplica {
   545  
   546  	if cvr.Annotations == nil {
   547  		return cvr.WithAnnotationsNew(annotations)
   548  	}
   549  	for key, value := range annotations {
   550  		cvr.Annotations[key] = value
   551  	}
   552  	return cvr
   553  }
   554  
   555  // WithLabelsNew sets the Lacvrels field of CV with provided arguments
   556  func (cvr *CStorVolumeReplica) WithLabelsNew(labels map[string]string) *CStorVolumeReplica {
   557  	cvr.Labels = make(map[string]string)
   558  	for key, value := range labels {
   559  		cvr.Labels[key] = value
   560  	}
   561  	return cvr
   562  }
   563  
   564  // WithLabels appends or overwrites existing Lacvrels
   565  // values of CVC with provided arguments
   566  func (cvr *CStorVolumeReplica) WithLabels(labels map[string]string) *CStorVolumeReplica {
   567  	if cvr.Labels == nil {
   568  		return cvr.WithLabelsNew(labels)
   569  	}
   570  	for key, value := range labels {
   571  		cvr.Labels[key] = value
   572  	}
   573  	return cvr
   574  }
   575  
   576  // WithFinalizers sets the finalizer field in the CV
   577  func (cvr *CStorVolumeReplica) WithFinalizers(finalizers ...string) *CStorVolumeReplica {
   578  	cvr.Finalizers = append(cvr.Finalizers, finalizers...)
   579  	return cvr
   580  }
   581  
   582  // WithOwnerReference sets the OwnerReference field in CV with required
   583  //fields
   584  func (cvr *CStorVolumeReplica) WithOwnerReference(reference []metav1.OwnerReference) *CStorVolumeReplica {
   585  	cvr.OwnerReferences = append(cvr.OwnerReferences, reference...)
   586  	return cvr
   587  }
   588  
   589  // WithTargetIP sets the target IP address field of
   590  // CStorVolumeReplica with provided arguments
   591  func (cvr *CStorVolumeReplica) WithTargetIP(targetip string) *CStorVolumeReplica {
   592  	cvr.Spec.TargetIP = targetip
   593  	return cvr
   594  }
   595  
   596  // WithCapacity sets the Capacity field of CStorVolumeReplica with provided arguments
   597  func (cvr *CStorVolumeReplica) WithCapacity(capacity string) *CStorVolumeReplica {
   598  	//	capacityQnt, _ := resource.ParseQuantity(capacity)
   599  	cvr.Spec.Capacity = capacity
   600  	return cvr
   601  }
   602  
   603  // WithReplicaID sets the replicaID with the provided arguments
   604  func (cvr *CStorVolumeReplica) WithReplicaID(replicaID string) *CStorVolumeReplica {
   605  	cvr.Spec.ReplicaID = replicaID
   606  	return cvr
   607  }
   608  
   609  // WithZvolWorkers sets the zvolworkers with the provided arguments
   610  func (cvr *CStorVolumeReplica) WithZvolWorkers(zvolworker string) *CStorVolumeReplica {
   611  	cvr.Spec.ZvolWorkers = zvolworker
   612  	return cvr
   613  }
   614  
   615  // WithCWithCompression sets the compression algorithm with the provided arguments
   616  func (cvr *CStorVolumeReplica) WithCompression(compression string) *CStorVolumeReplica {
   617  	cvr.Spec.Compression = compression
   618  	return cvr
   619  }
   620  
   621  // WithStatusPhase sets the Status Phase of CStorVolumeReplica with provided
   622  //arguments
   623  func (cvr *CStorVolumeReplica) WithStatusPhase(phase CStorVolumeReplicaPhase) *CStorVolumeReplica {
   624  	cvr.Status.Phase = phase
   625  	return cvr
   626  }
   627  
   628  // WithNewVersion sets the current and desired version field of
   629  // CV with provided arguments
   630  func (cvr *CStorVolumeReplica) WithNewVersion(version string) *CStorVolumeReplica {
   631  	cvr.VersionDetails.Status.Current = version
   632  	cvr.VersionDetails.Desired = version
   633  	return cvr
   634  }
   635  
   636  // WithDependentsUpgraded sets the field to true for new CV
   637  func (cvr *CStorVolumeReplica) WithDependentsUpgraded() *CStorVolumeReplica {
   638  	cvr.VersionDetails.Status.DependentsUpgraded = true
   639  	return cvr
   640  }
   641  
   642  // HasFinalizer returns true if the provided finalizer is present on the ocvrject.
   643  func (cvr *CStorVolumeReplica) HasFinalizer(finalizer string) bool {
   644  	finalizersList := cvr.GetFinalizers()
   645  	return util.ContainsString(finalizersList, finalizer)
   646  }
   647  
   648  // RemoveFinalizer removes the given finalizer from the ocvrject.
   649  func (cvr *CStorVolumeReplica) RemoveFinalizer(finalizer string) {
   650  	cvr.Finalizers = util.RemoveString(cvr.Finalizers, finalizer)
   651  }
   652  
   653  // GetPoolNames returns list of pool names from cStor volume replcia list
   654  func GetPoolNames(cvrList *CStorVolumeReplicaList) []string {
   655  	poolNames := []string{}
   656  	for _, cvrObj := range cvrList.Items {
   657  		poolNames = append(poolNames, cvrObj.Labels[string(types.CStorPoolInstanceNameLabelKey)])
   658  	}
   659  	return poolNames
   660  }