func parseVolumeAttributes()

in pkg/csi_driver/utils.go [191:266]


func parseVolumeAttributes(fuseMountOptions []string, volumeContext map[string]string) ([]string, bool, bool, error) {
	if mountOptions, ok := volumeContext[VolumeContextKeyMountOptions]; ok {
		fuseMountOptions = joinMountOptions(fuseMountOptions, strings.Split(mountOptions, ","))
	}
	skipCSIBucketAccessCheck := false
	disableMetricsCollection := false
	for volumeAttribute, mountOption := range volumeAttributesToMountOptionsMapping {
		value, ok := volumeContext[volumeAttribute]
		if !ok {
			continue
		}

		var mountOptionWithValue string
		switch volumeAttribute {
		// parse Quantity volume attributes,
		// the input value should be a valid Quantity defined in https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity/,
		// convert the input to a string representation in MB.
		case VolumeContextKeyFileCacheCapacity, VolumeContextKeyMetadataStatCacheCapacity, VolumeContextKeyMetadataTypeCacheCapacity:
			quantity, err := resource.ParseQuantity(value)
			if err != nil {
				return nil, skipCSIBucketAccessCheck, disableMetricsCollection, fmt.Errorf("volume attribute %v only accepts a valid Quantity value, got %q, error: %w", volumeAttribute, value, err)
			}

			megabytes := quantity.Value()
			switch {
			case megabytes < 0:
				value = "-1"
			case quantity.Format == resource.BinarySI:
				value = strconv.FormatInt(megabytes/1024/1024, 10)
			default:
				value = strconv.FormatInt(megabytes/1000/1000, 10)
			}

			mountOptionWithValue = mountOption + value

		// parse bool volume attributes
		case VolumeContextKeyFileCacheForRangeRead, VolumeContextKeySkipCSIBucketAccessCheck, VolumeContextKeyDisableMetrics:
			if boolVal, err := strconv.ParseBool(value); err == nil {
				if volumeAttribute == VolumeContextKeySkipCSIBucketAccessCheck {
					skipCSIBucketAccessCheck = boolVal

					// The skipCSIBucketAccessCheck volume attribute is only for CSI driver,
					// and there is no translation to GCSFuse mount options.
					continue
				}

				if volumeAttribute == VolumeContextKeyDisableMetrics {
					disableMetricsCollection = boolVal
				}

				mountOptionWithValue = mountOption + strconv.FormatBool(boolVal)
			} else {
				return nil, skipCSIBucketAccessCheck, disableMetricsCollection, fmt.Errorf("volume attribute %v only accepts a valid bool value, got %q", volumeAttribute, value)
			}

		// parse int volume attributes
		case VolumeContextKeyMetadataCacheTTLSeconds, VolumeContextKeyMetadataCacheTtlSeconds:
			if intVal, err := strconv.Atoi(value); err == nil {
				if intVal < 0 {
					intVal = -1
				}

				mountOptionWithValue = mountOption + strconv.Itoa(intVal)
			} else {
				return nil, skipCSIBucketAccessCheck, disableMetricsCollection, fmt.Errorf("volume attribute %v only accepts a valid int value, got %q", volumeAttribute, value)
			}

		default:
			mountOptionWithValue = mountOption + value
		}

		fuseMountOptions = joinMountOptions(fuseMountOptions, []string{mountOptionWithValue})
	}

	return fuseMountOptions, skipCSIBucketAccessCheck, disableMetricsCollection, nil
}