| /* |
| Copyright 2018 The Kubernetes Authors. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package storage |
| |
| import ( |
| "k8s.io/api/core/v1" |
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| "strings" |
| ) |
| |
| // TODO(yue9944882): Remove this helper package once it's copied to k/api |
| |
| // IsDefaultStorageClassAnnotation represents a StorageClass annotation that |
| // marks a class as the default StorageClass |
| const IsDefaultStorageClassAnnotation = "storageclass.kubernetes.io/is-default-class" |
| |
| // BetaIsDefaultStorageClassAnnotation is the beta version of BetaIsDefaultStorageClassAnnotation. |
| const BetaIsDefaultStorageClassAnnotation = "storageclass.beta.kubernetes.io/is-default-class" |
| |
| // IsDefaultAnnotationText returns a pretty Yes/No String if |
| // the annotation is set |
| func IsDefaultAnnotationText(obj metav1.ObjectMeta) string { |
| if obj.Annotations[IsDefaultStorageClassAnnotation] == "true" { |
| return "Yes" |
| } |
| if obj.Annotations[BetaIsDefaultStorageClassAnnotation] == "true" { |
| return "Yes" |
| } |
| |
| return "No" |
| } |
| |
| // GetAccessModesAsString returns a string representation of an array of access modes. |
| // modes, when present, are always in the same order: RWO,ROX,RWX. |
| func GetAccessModesAsString(modes []v1.PersistentVolumeAccessMode) string { |
| modes = removeDuplicateAccessModes(modes) |
| modesStr := []string{} |
| if containsAccessMode(modes, v1.ReadWriteOnce) { |
| modesStr = append(modesStr, "RWO") |
| } |
| if containsAccessMode(modes, v1.ReadOnlyMany) { |
| modesStr = append(modesStr, "ROX") |
| } |
| if containsAccessMode(modes, v1.ReadWriteMany) { |
| modesStr = append(modesStr, "RWX") |
| } |
| return strings.Join(modesStr, ",") |
| } |
| |
| // removeDuplicateAccessModes returns an array of access modes without any duplicates |
| func removeDuplicateAccessModes(modes []v1.PersistentVolumeAccessMode) []v1.PersistentVolumeAccessMode { |
| accessModes := []v1.PersistentVolumeAccessMode{} |
| for _, m := range modes { |
| if !containsAccessMode(accessModes, m) { |
| accessModes = append(accessModes, m) |
| } |
| } |
| return accessModes |
| } |
| |
| func containsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool { |
| for _, m := range modes { |
| if m == mode { |
| return true |
| } |
| } |
| return false |
| } |
| |
| // GetPersistentVolumeClass returns StorageClassName. |
| func GetPersistentVolumeClass(volume *v1.PersistentVolume) string { |
| // Use beta annotation first |
| if class, found := volume.Annotations[v1.BetaStorageClassAnnotation]; found { |
| return class |
| } |
| |
| return volume.Spec.StorageClassName |
| } |
| |
| // GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was |
| // requested, it returns "". |
| func GetPersistentVolumeClaimClass(claim *v1.PersistentVolumeClaim) string { |
| // Use beta annotation first |
| if class, found := claim.Annotations[v1.BetaStorageClassAnnotation]; found { |
| return class |
| } |
| |
| if claim.Spec.StorageClassName != nil { |
| return *claim.Spec.StorageClassName |
| } |
| |
| return "" |
| } |