Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage capacity GA #108445

Merged
merged 6 commits into from Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions api/api-rules/violation_exceptions.list
Expand Up @@ -253,6 +253,7 @@ API rule violation: list_type_missing,k8s.io/api/rbac/v1beta1,Role,Rules
API rule violation: list_type_missing,k8s.io/api/rbac/v1beta1,RoleBinding,Subjects
API rule violation: list_type_missing,k8s.io/api/storage/v1,CSINodeDriver,TopologyKeys
API rule violation: list_type_missing,k8s.io/api/storage/v1,CSINodeSpec,Drivers
API rule violation: list_type_missing,k8s.io/api/storage/v1,CSIStorageCapacityList,Items
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filed kubernetes/kube-openapi#281 to avoid this noise

API rule violation: list_type_missing,k8s.io/api/storage/v1,StorageClass,MountOptions
API rule violation: list_type_missing,k8s.io/api/storage/v1alpha1,CSIStorageCapacityList,Items
API rule violation: list_type_missing,k8s.io/api/storage/v1beta1,CSIDriverSpec,VolumeLifecycleModes
Expand Down
1,435 changes: 1,300 additions & 135 deletions api/openapi-spec/swagger.json

Large diffs are not rendered by default.

1,974 changes: 1,704 additions & 270 deletions api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json

Large diffs are not rendered by default.

Expand Up @@ -2,15 +2,15 @@
"components": {
"schemas": {
"io.k8s.api.storage.v1alpha1.CSIStorageCapacity": {
"description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.",
"description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"capacity": {
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity",
"description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity."
"description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable."
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
Expand Down
Expand Up @@ -2,15 +2,15 @@
"components": {
"schemas": {
"io.k8s.api.storage.v1beta1.CSIStorageCapacity": {
"description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.",
"description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"capacity": {
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity",
"description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable and treated like zero capacity."
"description": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable."
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
Expand Down
17 changes: 9 additions & 8 deletions pkg/apis/storage/types.go
Expand Up @@ -357,9 +357,6 @@ type CSIDriverSpec struct {
//
// This field was immutable in Kubernetes <= 1.22 and now is mutable.
//
// This is a beta field and only available when the CSIStorageCapacity
// feature is enabled. The default is false.
//
// +optional
StorageCapacity *bool

Expand Down Expand Up @@ -575,9 +572,13 @@ type CSINodeList struct {
//
// The producer of these objects can decide which approach is more suitable.
//
// They are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate
// is enabled there and a CSI driver opts into capacity-aware scheduling with
// CSIDriver.StorageCapacity.
// They are consumed by the kube-scheduler when a CSI driver opts into
// capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler
// compares the MaximumVolumeSize against the requested size of pending volumes
// to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back
// to a comparison against the less precise Capacity. If that is also unset,
// the scheduler assumes that capacity is insufficient and tries some other
// node.
type CSIStorageCapacity struct {
metav1.TypeMeta
// Standard object's metadata. The name has no particular meaning. It must be
Expand All @@ -595,7 +596,7 @@ type CSIStorageCapacity struct {
// NodeTopology defines which nodes have access to the storage
// for which capacity was reported. If not set, the storage is
// not accessible from any node in the cluster. If empty, the
// storage is accessible from all nodes. This field is
// storage is accessible from all nodes. This field is
// immutable.
//
// +optional
Expand All @@ -616,7 +617,7 @@ type CSIStorageCapacity struct {
// The semantic is currently (CSI spec 1.2) defined as:
// The available capacity, in bytes, of the storage that can be used
// to provision volumes. If not set, that information is currently
// unavailable and treated like zero capacity.
// unavailable.
//
// +optional
Capacity *resource.Quantity
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/storage/v1/defaults.go
Expand Up @@ -49,7 +49,7 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
obj.Spec.PodInfoOnMount = new(bool)
*(obj.Spec.PodInfoOnMount) = false
}
if obj.Spec.StorageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
if obj.Spec.StorageCapacity == nil {
obj.Spec.StorageCapacity = new(bool)
*(obj.Spec.StorageCapacity) = false
}
Expand Down
13 changes: 0 additions & 13 deletions pkg/apis/storage/v1/defaults_test.go
Expand Up @@ -52,7 +52,6 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
}

func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)()
driver := &storagev1.CSIDriver{}

// field should be defaulted
Expand All @@ -66,18 +65,6 @@ func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
}
}

func TestSetDefaultStorageCapacityDisabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, false)()
driver := &storagev1.CSIDriver{}

// field should not be defaulted
output := roundTrip(t, runtime.Object(driver)).(*storagev1.CSIDriver)
outStorageCapacity := output.Spec.StorageCapacity
if outStorageCapacity != nil {
t.Errorf("Expected StorageCapacity to remain nil, got: %+v", outStorageCapacity)
}
}

func TestSetDefaultVolumeBindingMode(t *testing.T) {
class := &storagev1.StorageClass{}

Expand Down
72 changes: 72 additions & 0 deletions pkg/apis/storage/v1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/apis/storage/v1beta1/defaults.go
Expand Up @@ -49,7 +49,7 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
obj.Spec.PodInfoOnMount = new(bool)
*(obj.Spec.PodInfoOnMount) = false
}
if obj.Spec.StorageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
if obj.Spec.StorageCapacity == nil {
obj.Spec.StorageCapacity = new(bool)
*(obj.Spec.StorageCapacity) = false
}
Expand Down
13 changes: 0 additions & 13 deletions pkg/apis/storage/v1beta1/defaults_test.go
Expand Up @@ -87,7 +87,6 @@ func TestSetDefaultAttachRequired(t *testing.T) {
}

func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, true)()
driver := &storagev1beta1.CSIDriver{}

// field should be defaulted
Expand All @@ -101,18 +100,6 @@ func TestSetDefaultStorageCapacityEnabled(t *testing.T) {
}
}

func TestSetDefaultStorageCapacityDisabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, false)()
driver := &storagev1beta1.CSIDriver{}

// field should not be defaulted
output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver)
outStorageCapacity := output.Spec.StorageCapacity
if outStorageCapacity != nil {
t.Errorf("Expected StorageCapacity to remain nil, got: %+v", outStorageCapacity)
}
}

func TestSetDefaultVolumeLifecycleModesEnabled(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
driver := &storagev1beta1.CSIDriver{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/storage/validation/validation.go
Expand Up @@ -469,7 +469,7 @@ func validatePodInfoOnMount(podInfoOnMount *bool, fldPath *field.Path) field.Err
// validateStorageCapacity tests if storageCapacity is set for CSIDriver.
func validateStorageCapacity(storageCapacity *bool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if storageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
if storageCapacity == nil {
allErrs = append(allErrs, field.Required(fldPath, ""))
}

Expand Down