mirror of https://github.com/k3s-io/k3s
Add ReclaimPolicy field to StorageClass
parent
bc1a58ae3a
commit
0356a840ff
|
@ -138,6 +138,10 @@ func TestDefaulting(t *testing.T) {
|
|||
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ExternalAdmissionHookConfigurationList"}: {},
|
||||
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"}: {},
|
||||
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicyList"}: {},
|
||||
{Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClass"}: {},
|
||||
{Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClassList"}: {},
|
||||
{Group: "storage.k8s.io", Version: "v1", Kind: "StorageClass"}: {},
|
||||
{Group: "storage.k8s.io", Version: "v1", Kind: "StorageClassList"}: {},
|
||||
}
|
||||
|
||||
f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))
|
||||
|
|
|
@ -40,6 +40,7 @@ import (
|
|||
extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
policyfuzzer "k8s.io/kubernetes/pkg/apis/policy/fuzzer"
|
||||
rbacfuzzer "k8s.io/kubernetes/pkg/apis/rbac/fuzzer"
|
||||
storagefuzzer "k8s.io/kubernetes/pkg/apis/storage/fuzzer"
|
||||
)
|
||||
|
||||
// overrideGenericFuncs override some generic fuzzer funcs from k8s.io/apiserver in order to have more realistic
|
||||
|
@ -100,4 +101,5 @@ var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
|
|||
policyfuzzer.Funcs,
|
||||
certificatesfuzzer.Funcs,
|
||||
admissionregistrationfuzzer.Funcs,
|
||||
storagefuzzer.Funcs,
|
||||
)
|
||||
|
|
|
@ -17,10 +17,20 @@ limitations under the License.
|
|||
package fuzzer
|
||||
|
||||
import (
|
||||
fuzz "github.com/google/gofuzz"
|
||||
|
||||
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
)
|
||||
|
||||
// Funcs returns the fuzzer functions for the storage api group.
|
||||
var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
return []interface{}{}
|
||||
return []interface{}{
|
||||
func(obj *storage.StorageClass, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj) // fuzz self without calling this function again
|
||||
reclamationPolicies := []api.PersistentVolumeReclaimPolicy{api.PersistentVolumeReclaimDelete, api.PersistentVolumeReclaimRetain}
|
||||
obj.ReclaimPolicy = &reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))]
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@ limitations under the License.
|
|||
|
||||
package storage
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
|
@ -46,6 +49,11 @@ type StorageClass struct {
|
|||
// 512, with a cumulative max size of 256K
|
||||
// +optional
|
||||
Parameters map[string]string
|
||||
|
||||
// reclaimPolicy is the reclaim policy that dynamically provisioned
|
||||
// PersistentVolumes of this storage class are created with
|
||||
// +optional
|
||||
ReclaimPolicy *api.PersistentVolumeReclaimPolicy
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2017 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 v1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_StorageClass(obj *storagev1.StorageClass) {
|
||||
if obj.ReclaimPolicy == nil {
|
||||
obj.ReclaimPolicy = new(v1.PersistentVolumeReclaimPolicy)
|
||||
*obj.ReclaimPolicy = v1.PersistentVolumeReclaimDelete
|
||||
}
|
||||
}
|
|
@ -41,5 +41,5 @@ func init() {
|
|||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(RegisterDefaults)
|
||||
localSchemeBuilder.Register(addDefaultingFuncs)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2017 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 v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
storagev1beta1 "k8s.io/api/storage/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_StorageClass(obj *storagev1beta1.StorageClass) {
|
||||
if obj.ReclaimPolicy == nil {
|
||||
obj.ReclaimPolicy = new(v1.PersistentVolumeReclaimPolicy)
|
||||
*obj.ReclaimPolicy = v1.PersistentVolumeReclaimDelete
|
||||
}
|
||||
}
|
|
@ -41,5 +41,5 @@ func init() {
|
|||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(RegisterDefaults)
|
||||
localSchemeBuilder.Register(addDefaultingFuncs)
|
||||
}
|
||||
|
|
|
@ -20,8 +20,10 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apivalidation "k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
)
|
||||
|
@ -31,6 +33,7 @@ func ValidateStorageClass(storageClass *storage.StorageClass) field.ErrorList {
|
|||
allErrs := apivalidation.ValidateObjectMeta(&storageClass.ObjectMeta, false, apivalidation.ValidateClassName, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, validateProvisioner(storageClass.Provisioner, field.NewPath("provisioner"))...)
|
||||
allErrs = append(allErrs, validateParameters(storageClass.Parameters, field.NewPath("parameters"))...)
|
||||
allErrs = append(allErrs, validateReclaimPolicy(storageClass.ReclaimPolicy, field.NewPath("reclaimPolicy"))...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
@ -45,6 +48,10 @@ func ValidateStorageClassUpdate(storageClass, oldStorageClass *storage.StorageCl
|
|||
if storageClass.Provisioner != oldStorageClass.Provisioner {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("provisioner"), "updates to provisioner are forbidden."))
|
||||
}
|
||||
|
||||
if *storageClass.ReclaimPolicy != *oldStorageClass.ReclaimPolicy {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("reclaimPolicy"), "updates to reclaimPolicy are forbidden."))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
@ -87,3 +94,17 @@ func validateParameters(params map[string]string, fldPath *field.Path) field.Err
|
|||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
var supportedReclaimPolicy = sets.NewString(string(api.PersistentVolumeReclaimDelete), string(api.PersistentVolumeReclaimRetain))
|
||||
|
||||
// validateReclaimPolicy tests that the reclaim policy is one of the supported. It is up to the volume plugin to reject
|
||||
// provisioning for storage classes with impossible reclaim policies, e.g. EBS is not Recyclable
|
||||
func validateReclaimPolicy(reclaimPolicy *api.PersistentVolumeReclaimPolicy, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(string(*reclaimPolicy)) > 0 {
|
||||
if !supportedReclaimPolicy.Has(string(*reclaimPolicy)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath, reclaimPolicy, supportedReclaimPolicy.List()))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
|
|
@ -21,21 +21,27 @@ import (
|
|||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
)
|
||||
|
||||
func TestValidateStorageClass(t *testing.T) {
|
||||
deleteReclaimPolicy := api.PersistentVolumeReclaimPolicy("Delete")
|
||||
retainReclaimPolicy := api.PersistentVolumeReclaimPolicy("Retain")
|
||||
recycleReclaimPolicy := api.PersistentVolumeReclaimPolicy("Recycle")
|
||||
successCases := []storage.StorageClass{
|
||||
{
|
||||
// empty parameters
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo-provisioner",
|
||||
Parameters: map[string]string{},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo-provisioner",
|
||||
Parameters: map[string]string{},
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
{
|
||||
// nil parameters
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo-provisioner",
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo-provisioner",
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
{
|
||||
// some parameters
|
||||
|
@ -46,6 +52,13 @@ func TestValidateStorageClass(t *testing.T) {
|
|||
"foo-parameter": "free-form-string",
|
||||
"foo-parameter2": "{\"embedded\": \"json\", \"with\": {\"structures\":\"inside\"}}",
|
||||
},
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
{
|
||||
// retain reclaimPolicy
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo-provisioner",
|
||||
ReclaimPolicy: &retainReclaimPolicy,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -68,12 +81,14 @@ func TestValidateStorageClass(t *testing.T) {
|
|||
|
||||
errorCases := map[string]storage.StorageClass{
|
||||
"namespace is present": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
|
||||
Provisioner: "kubernetes.io/foo-provisioner",
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
|
||||
Provisioner: "kubernetes.io/foo-provisioner",
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
"invalid provisioner": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/invalid/provisioner",
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/invalid/provisioner",
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
"invalid empty parameter name": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
|
@ -81,15 +96,23 @@ func TestValidateStorageClass(t *testing.T) {
|
|||
Parameters: map[string]string{
|
||||
"": "value",
|
||||
},
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
"provisioner: Required value": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "",
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "",
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
"too long parameters": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo",
|
||||
Parameters: longParameters,
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo",
|
||||
Parameters: longParameters,
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
"invalid reclaimpolicy": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Provisioner: "kubernetes.io/foo",
|
||||
ReclaimPolicy: &recycleReclaimPolicy,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ var class1Parameters = map[string]string{
|
|||
var class2Parameters = map[string]string{
|
||||
"param2": "value2",
|
||||
}
|
||||
var deleteReclaimPolicy = v1.PersistentVolumeReclaimDelete
|
||||
var storageClasses = []*storage.StorageClass{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
|
@ -41,8 +42,9 @@ var storageClasses = []*storage.StorageClass{
|
|||
Name: "gold",
|
||||
},
|
||||
|
||||
Provisioner: mockPluginName,
|
||||
Parameters: class1Parameters,
|
||||
Provisioner: mockPluginName,
|
||||
Parameters: class1Parameters,
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
|
@ -51,8 +53,9 @@ var storageClasses = []*storage.StorageClass{
|
|||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "silver",
|
||||
},
|
||||
Provisioner: mockPluginName,
|
||||
Parameters: class2Parameters,
|
||||
Provisioner: mockPluginName,
|
||||
Parameters: class2Parameters,
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
|
@ -61,8 +64,9 @@ var storageClasses = []*storage.StorageClass{
|
|||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "external",
|
||||
},
|
||||
Provisioner: "vendor.com/my-volume",
|
||||
Parameters: class1Parameters,
|
||||
Provisioner: "vendor.com/my-volume",
|
||||
Parameters: class1Parameters,
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
|
@ -71,8 +75,9 @@ var storageClasses = []*storage.StorageClass{
|
|||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "unknown-internal",
|
||||
},
|
||||
Provisioner: "kubernetes.io/unknown",
|
||||
Parameters: class1Parameters,
|
||||
Provisioner: "kubernetes.io/unknown",
|
||||
Parameters: class1Parameters,
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1309,7 +1309,7 @@ func (ctrl *PersistentVolumeController) provisionClaimOperation(claimObj interfa
|
|||
tags[CloudVolumeCreatedForVolumeNameTag] = pvName
|
||||
|
||||
options := vol.VolumeOptions{
|
||||
PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete,
|
||||
PersistentVolumeReclaimPolicy: *storageClass.ReclaimPolicy,
|
||||
CloudTags: &tags,
|
||||
ClusterName: ctrl.clusterName,
|
||||
PVName: pvName,
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
storageapi "k8s.io/kubernetes/pkg/apis/storage"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
)
|
||||
|
@ -42,6 +43,7 @@ func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
|
|||
}
|
||||
|
||||
func validNewStorageClass(name string) *storageapi.StorageClass {
|
||||
deleteReclaimPolicy := api.PersistentVolumeReclaimDelete
|
||||
return &storageapi.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
|
@ -50,6 +52,7 @@ func validNewStorageClass(name string) *storageapi.StorageClass {
|
|||
Parameters: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,12 +67,14 @@ func TestCreate(t *testing.T) {
|
|||
test := registrytest.New(t, storage.Store).ClusterScope()
|
||||
storageClass := validNewStorageClass("foo")
|
||||
storageClass.ObjectMeta = metav1.ObjectMeta{GenerateName: "foo"}
|
||||
deleteReclaimPolicy := api.PersistentVolumeReclaimDelete
|
||||
test.TestCreate(
|
||||
// valid
|
||||
storageClass,
|
||||
// invalid
|
||||
&storageapi.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"},
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
)
|
||||
|
||||
|
@ -33,6 +34,7 @@ func TestStorageClassStrategy(t *testing.T) {
|
|||
t.Errorf("StorageClass should not allow create on update")
|
||||
}
|
||||
|
||||
deleteReclaimPolicy := api.PersistentVolumeReclaimDelete
|
||||
storageClass := &storage.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid-class",
|
||||
|
@ -41,6 +43,7 @@ func TestStorageClassStrategy(t *testing.T) {
|
|||
Parameters: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
}
|
||||
|
||||
Strategy.PrepareForCreate(ctx, storageClass)
|
||||
|
@ -59,6 +62,7 @@ func TestStorageClassStrategy(t *testing.T) {
|
|||
Parameters: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
ReclaimPolicy: &deleteReclaimPolicy,
|
||||
}
|
||||
|
||||
Strategy.PrepareForUpdate(ctx, newStorageClass, storageClass)
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -43,6 +44,11 @@ type StorageClass struct {
|
|||
// create volumes of this storage class.
|
||||
// +optional
|
||||
Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"`
|
||||
|
||||
// Dynamically provisioned PersistentVolumes of this storage class are
|
||||
// created with this reclaimPolicy. Defaults to Delete.
|
||||
// +optional
|
||||
ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -43,6 +44,11 @@ type StorageClass struct {
|
|||
// create volumes of this storage class.
|
||||
// +optional
|
||||
Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"`
|
||||
|
||||
// Dynamically provisioned PersistentVolumes of this storage class are
|
||||
// created with this reclaimPolicy. Defaults to Delete.
|
||||
// +optional
|
||||
ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
Loading…
Reference in New Issue