plumb service account token down to csi driver

This commit is contained in:
Shihang Zhang 2020-07-09 13:54:51 -07:00
parent f4a156eb29
commit d2859cd89b
80 changed files with 2178 additions and 408 deletions

View File

@ -15204,10 +15204,22 @@
"description": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" iff the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.", "description": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" iff the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.",
"type": "boolean" "type": "boolean"
}, },
"requiresRepublish": {
"description": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
"type": "boolean"
},
"storageCapacity": { "storageCapacity": {
"description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.", "description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.",
"type": "boolean" "type": "boolean"
}, },
"tokenRequests": {
"description": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"<audience>\": {\n \"token\": <token>,\n \"expirationTimestamp\": <expiration timestamp in RFC3339>,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
"items": {
"$ref": "#/definitions/io.k8s.api.storage.v1.TokenRequest"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"volumeLifecycleModes": { "volumeLifecycleModes": {
"description": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.", "description": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.",
"items": { "items": {
@ -15433,6 +15445,24 @@
} }
] ]
}, },
"io.k8s.api.storage.v1.TokenRequest": {
"description": "TokenRequest contains parameters of a service account token.",
"properties": {
"audience": {
"description": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.",
"type": "string"
},
"expirationSeconds": {
"description": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\".",
"format": "int64",
"type": "integer"
}
},
"required": [
"audience"
],
"type": "object"
},
"io.k8s.api.storage.v1.VolumeAttachment": { "io.k8s.api.storage.v1.VolumeAttachment": {
"description": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "description": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.",
"properties": { "properties": {
@ -15826,10 +15856,22 @@
"description": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" iff the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.", "description": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" iff the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.",
"type": "boolean" "type": "boolean"
}, },
"requiresRepublish": {
"description": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
"type": "boolean"
},
"storageCapacity": { "storageCapacity": {
"description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.", "description": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.",
"type": "boolean" "type": "boolean"
}, },
"tokenRequests": {
"description": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"<audience>\": {\n \"token\": <token>,\n \"expirationTimestamp\": <expiration timestamp in RFC3339>,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
"items": {
"$ref": "#/definitions/io.k8s.api.storage.v1beta1.TokenRequest"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"volumeLifecycleModes": { "volumeLifecycleModes": {
"description": "VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.", "description": "VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.",
"items": { "items": {
@ -16054,6 +16096,24 @@
} }
] ]
}, },
"io.k8s.api.storage.v1beta1.TokenRequest": {
"description": "TokenRequest contains parameters of a service account token.",
"properties": {
"audience": {
"description": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.",
"type": "string"
},
"expirationSeconds": {
"description": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\"",
"format": "int64",
"type": "integer"
}
},
"required": [
"audience"
],
"type": "object"
},
"io.k8s.api.storage.v1beta1.VolumeAttachment": { "io.k8s.api.storage.v1beta1.VolumeAttachment": {
"description": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "description": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.",
"properties": { "properties": {

View File

@ -87,6 +87,10 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
obj.Spec.FSGroupPolicy = new(storage.FSGroupPolicy) obj.Spec.FSGroupPolicy = new(storage.FSGroupPolicy)
*obj.Spec.FSGroupPolicy = storage.ReadWriteOnceWithFSTypeFSGroupPolicy *obj.Spec.FSGroupPolicy = storage.ReadWriteOnceWithFSTypeFSGroupPolicy
} }
if obj.Spec.RequiresRepublish == nil {
obj.Spec.RequiresRepublish = new(bool)
*(obj.Spec.RequiresRepublish) = false
}
if len(obj.Spec.VolumeLifecycleModes) == 0 { if len(obj.Spec.VolumeLifecycleModes) == 0 {
obj.Spec.VolumeLifecycleModes = []storage.VolumeLifecycleMode{ obj.Spec.VolumeLifecycleModes = []storage.VolumeLifecycleMode{
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,

View File

@ -337,6 +337,43 @@ type CSIDriverSpec struct {
// //
// +optional // +optional
StorageCapacity *bool StorageCapacity *bool
// TokenRequests indicates the CSI driver needs pods' service account
// tokens it is mounting volume for to do necessary authentication. Kubelet
// will pass the tokens in VolumeContext in the CSI NodePublishVolume calls.
// The CSI driver should parse and validate the following VolumeContext:
// "csi.storage.k8s.io/serviceAccount.tokens": {
// "<audience>": {
// "token": <token>,
// "expirationTimestamp": <expiration timestamp in RFC3339>,
// },
// ...
// }
//
// Note: Audience in each TokenRequest should be different and at
// most one token is empty string. To receive a new token after expiry,
// RequiresRepublish can be used to trigger NodePublishVolume periodically.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
// +listType=atomic
TokenRequests []TokenRequest
// RequiresRepublish indicates the CSI driver wants `NodePublishVolume`
// being periodically called to reflect any possible change in the mounted
// volume. This field defaults to false.
//
// Note: After a successful initial NodePublishVolume call, subsequent calls
// to NodePublishVolume should only update the contents of the volume. New
// mount points will not be seen by a running container.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
RequiresRepublish *bool
} }
// FSGroupPolicy specifies if a CSI Driver supports modifying // FSGroupPolicy specifies if a CSI Driver supports modifying
@ -374,6 +411,20 @@ const (
// More modes may be added in the future. // More modes may be added in the future.
type VolumeLifecycleMode string type VolumeLifecycleMode string
// TokenRequest contains parameters of a service account token.
type TokenRequest struct {
// Audience is the intended audience of the token in "TokenRequestSpec".
// It will default to the audiences of kube apiserver.
//
Audience string
// ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec".
// It has the same default value of "ExpirationSeconds" in "TokenRequestSpec."
//
// +optional
ExpirationSeconds *int64
}
const ( const (
// VolumeLifecyclePersistent explicitly confirms that the driver implements // VolumeLifecyclePersistent explicitly confirms that the driver implements
// the full CSI spec. It is the default when CSIDriverSpec.VolumeLifecycleModes is not // the full CSI spec. It is the default when CSIDriverSpec.VolumeLifecycleModes is not

View File

@ -58,5 +58,6 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library", "//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
], ],
) )

View File

@ -60,4 +60,8 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) { if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1.VolumeLifecyclePersistent) obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1.VolumeLifecyclePersistent)
} }
if obj.Spec.RequiresRepublish == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
obj.Spec.RequiresRepublish = new(bool)
*(obj.Spec.RequiresRepublish) = false
}
} }

View File

@ -20,6 +20,7 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/google/go-cmp/cmp"
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
@ -90,3 +91,48 @@ func TestSetDefaultVolumeBindingMode(t *testing.T) {
t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode) t.Errorf("Expected VolumeBindingMode to be defaulted to: %+v, got: %+v", defaultMode, outMode)
} }
} }
func TestSetDefaultCSIDriver(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIServiceAccountToken, true)()
enabled := true
disabled := false
tests := []struct {
desc string
field string
wantSpec *storagev1.CSIDriverSpec
}{
{
desc: "AttachRequired default to true",
field: "AttachRequired",
wantSpec: &storagev1.CSIDriverSpec{AttachRequired: &enabled},
},
{
desc: "PodInfoOnMount default to false",
field: "PodInfoOnMount",
wantSpec: &storagev1.CSIDriverSpec{PodInfoOnMount: &disabled},
},
{
desc: "VolumeLifecycleModes default to VolumeLifecyclePersistent",
field: "VolumeLifecycleModes",
wantSpec: &storagev1.CSIDriverSpec{VolumeLifecycleModes: []storagev1.VolumeLifecycleMode{storagev1.VolumeLifecyclePersistent}},
},
{
desc: "RequiresRepublish default to false",
field: "RequiresRepublish",
wantSpec: &storagev1.CSIDriverSpec{RequiresRepublish: &disabled},
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
gotSpec := roundTrip(t, runtime.Object(&storagev1.CSIDriver{})).(*storagev1.CSIDriver).Spec
got := reflect.Indirect(reflect.ValueOf(gotSpec)).FieldByName(test.field).Interface()
want := reflect.Indirect(reflect.ValueOf(test.wantSpec)).FieldByName(test.field).Interface()
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("CSIDriver defaults diff (-want +got):\n%s", diff)
}
})
}
}

View File

@ -129,6 +129,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*v1.TokenRequest)(nil), (*storage.TokenRequest)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_TokenRequest_To_storage_TokenRequest(a.(*v1.TokenRequest), b.(*storage.TokenRequest), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*storage.TokenRequest)(nil), (*v1.TokenRequest)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_storage_TokenRequest_To_v1_TokenRequest(a.(*storage.TokenRequest), b.(*v1.TokenRequest), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1.VolumeAttachment)(nil), (*storage.VolumeAttachment)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*v1.VolumeAttachment)(nil), (*storage.VolumeAttachment)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_VolumeAttachment_To_storage_VolumeAttachment(a.(*v1.VolumeAttachment), b.(*storage.VolumeAttachment), scope) return Convert_v1_VolumeAttachment_To_storage_VolumeAttachment(a.(*v1.VolumeAttachment), b.(*storage.VolumeAttachment), scope)
}); err != nil { }); err != nil {
@ -276,6 +286,8 @@ func autoConvert_v1_CSIDriverSpec_To_storage_CSIDriverSpec(in *v1.CSIDriverSpec,
out.VolumeLifecycleModes = *(*[]storage.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes)) out.VolumeLifecycleModes = *(*[]storage.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes))
out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity)) out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity))
out.FSGroupPolicy = (*storage.FSGroupPolicy)(unsafe.Pointer(in.FSGroupPolicy)) out.FSGroupPolicy = (*storage.FSGroupPolicy)(unsafe.Pointer(in.FSGroupPolicy))
out.TokenRequests = *(*[]storage.TokenRequest)(unsafe.Pointer(&in.TokenRequests))
out.RequiresRepublish = (*bool)(unsafe.Pointer(in.RequiresRepublish))
return nil return nil
} }
@ -290,6 +302,8 @@ func autoConvert_storage_CSIDriverSpec_To_v1_CSIDriverSpec(in *storage.CSIDriver
out.PodInfoOnMount = (*bool)(unsafe.Pointer(in.PodInfoOnMount)) out.PodInfoOnMount = (*bool)(unsafe.Pointer(in.PodInfoOnMount))
out.VolumeLifecycleModes = *(*[]v1.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes)) out.VolumeLifecycleModes = *(*[]v1.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes))
out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity)) out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity))
out.TokenRequests = *(*[]v1.TokenRequest)(unsafe.Pointer(&in.TokenRequests))
out.RequiresRepublish = (*bool)(unsafe.Pointer(in.RequiresRepublish))
return nil return nil
} }
@ -448,6 +462,28 @@ func Convert_storage_StorageClassList_To_v1_StorageClassList(in *storage.Storage
return autoConvert_storage_StorageClassList_To_v1_StorageClassList(in, out, s) return autoConvert_storage_StorageClassList_To_v1_StorageClassList(in, out, s)
} }
func autoConvert_v1_TokenRequest_To_storage_TokenRequest(in *v1.TokenRequest, out *storage.TokenRequest, s conversion.Scope) error {
out.Audience = in.Audience
out.ExpirationSeconds = (*int64)(unsafe.Pointer(in.ExpirationSeconds))
return nil
}
// Convert_v1_TokenRequest_To_storage_TokenRequest is an autogenerated conversion function.
func Convert_v1_TokenRequest_To_storage_TokenRequest(in *v1.TokenRequest, out *storage.TokenRequest, s conversion.Scope) error {
return autoConvert_v1_TokenRequest_To_storage_TokenRequest(in, out, s)
}
func autoConvert_storage_TokenRequest_To_v1_TokenRequest(in *storage.TokenRequest, out *v1.TokenRequest, s conversion.Scope) error {
out.Audience = in.Audience
out.ExpirationSeconds = (*int64)(unsafe.Pointer(in.ExpirationSeconds))
return nil
}
// Convert_storage_TokenRequest_To_v1_TokenRequest is an autogenerated conversion function.
func Convert_storage_TokenRequest_To_v1_TokenRequest(in *storage.TokenRequest, out *v1.TokenRequest, s conversion.Scope) error {
return autoConvert_storage_TokenRequest_To_v1_TokenRequest(in, out, s)
}
func autoConvert_v1_VolumeAttachment_To_storage_VolumeAttachment(in *v1.VolumeAttachment, out *storage.VolumeAttachment, s conversion.Scope) error { func autoConvert_v1_VolumeAttachment_To_storage_VolumeAttachment(in *v1.VolumeAttachment, out *storage.VolumeAttachment, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta out.ObjectMeta = in.ObjectMeta
if err := Convert_v1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_v1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(&in.Spec, &out.Spec, s); err != nil {

View File

@ -58,5 +58,6 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library", "//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
], ],
) )

View File

@ -60,4 +60,8 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) { if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1beta1.VolumeLifecyclePersistent) obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1beta1.VolumeLifecyclePersistent)
} }
if obj.Spec.RequiresRepublish == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
obj.Spec.RequiresRepublish = new(bool)
*(obj.Spec.RequiresRepublish) = false
}
} }

View File

@ -20,6 +20,7 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/google/go-cmp/cmp"
storagev1beta1 "k8s.io/api/storage/v1beta1" storagev1beta1 "k8s.io/api/storage/v1beta1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
@ -138,3 +139,43 @@ func TestSetDefaultVolumeLifecycleModesDisabled(t *testing.T) {
t.Errorf("Expected VolumeLifecycleModes to remain nil, got: %+v", outModes) t.Errorf("Expected VolumeLifecycleModes to remain nil, got: %+v", outModes)
} }
} }
func TestSetDefaultCSIDriver(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIServiceAccountToken, true)()
enabled := true
disabled := false
tests := []struct {
desc string
field string
wantSpec *storagev1beta1.CSIDriverSpec
}{
{
desc: "AttachRequired default to true",
field: "AttachRequired",
wantSpec: &storagev1beta1.CSIDriverSpec{AttachRequired: &enabled},
},
{
desc: "PodInfoOnMount default to false",
field: "PodInfoOnMount",
wantSpec: &storagev1beta1.CSIDriverSpec{PodInfoOnMount: &disabled},
},
{
desc: "RequiresRepublish default to false",
field: "RequiresRepublish",
wantSpec: &storagev1beta1.CSIDriverSpec{RequiresRepublish: &disabled},
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
gotSpec := roundTrip(t, runtime.Object(&storagev1beta1.CSIDriver{})).(*storagev1beta1.CSIDriver).Spec
got := reflect.Indirect(reflect.ValueOf(gotSpec)).FieldByName(test.field).Interface()
want := reflect.Indirect(reflect.ValueOf(test.wantSpec)).FieldByName(test.field).Interface()
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("CSIDriver defaults diff (-want +got):\n%s", diff)
}
})
}
}

View File

@ -129,6 +129,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*v1beta1.TokenRequest)(nil), (*storage.TokenRequest)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta1_TokenRequest_To_storage_TokenRequest(a.(*v1beta1.TokenRequest), b.(*storage.TokenRequest), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*storage.TokenRequest)(nil), (*v1beta1.TokenRequest)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_storage_TokenRequest_To_v1beta1_TokenRequest(a.(*storage.TokenRequest), b.(*v1beta1.TokenRequest), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1beta1.VolumeAttachment)(nil), (*storage.VolumeAttachment)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*v1beta1.VolumeAttachment)(nil), (*storage.VolumeAttachment)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta1_VolumeAttachment_To_storage_VolumeAttachment(a.(*v1beta1.VolumeAttachment), b.(*storage.VolumeAttachment), scope) return Convert_v1beta1_VolumeAttachment_To_storage_VolumeAttachment(a.(*v1beta1.VolumeAttachment), b.(*storage.VolumeAttachment), scope)
}); err != nil { }); err != nil {
@ -276,6 +286,8 @@ func autoConvert_v1beta1_CSIDriverSpec_To_storage_CSIDriverSpec(in *v1beta1.CSID
out.VolumeLifecycleModes = *(*[]storage.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes)) out.VolumeLifecycleModes = *(*[]storage.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes))
out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity)) out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity))
out.FSGroupPolicy = (*storage.FSGroupPolicy)(unsafe.Pointer(in.FSGroupPolicy)) out.FSGroupPolicy = (*storage.FSGroupPolicy)(unsafe.Pointer(in.FSGroupPolicy))
out.TokenRequests = *(*[]storage.TokenRequest)(unsafe.Pointer(&in.TokenRequests))
out.RequiresRepublish = (*bool)(unsafe.Pointer(in.RequiresRepublish))
return nil return nil
} }
@ -290,6 +302,8 @@ func autoConvert_storage_CSIDriverSpec_To_v1beta1_CSIDriverSpec(in *storage.CSID
out.PodInfoOnMount = (*bool)(unsafe.Pointer(in.PodInfoOnMount)) out.PodInfoOnMount = (*bool)(unsafe.Pointer(in.PodInfoOnMount))
out.VolumeLifecycleModes = *(*[]v1beta1.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes)) out.VolumeLifecycleModes = *(*[]v1beta1.VolumeLifecycleMode)(unsafe.Pointer(&in.VolumeLifecycleModes))
out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity)) out.StorageCapacity = (*bool)(unsafe.Pointer(in.StorageCapacity))
out.TokenRequests = *(*[]v1beta1.TokenRequest)(unsafe.Pointer(&in.TokenRequests))
out.RequiresRepublish = (*bool)(unsafe.Pointer(in.RequiresRepublish))
return nil return nil
} }
@ -448,6 +462,28 @@ func Convert_storage_StorageClassList_To_v1beta1_StorageClassList(in *storage.St
return autoConvert_storage_StorageClassList_To_v1beta1_StorageClassList(in, out, s) return autoConvert_storage_StorageClassList_To_v1beta1_StorageClassList(in, out, s)
} }
func autoConvert_v1beta1_TokenRequest_To_storage_TokenRequest(in *v1beta1.TokenRequest, out *storage.TokenRequest, s conversion.Scope) error {
out.Audience = in.Audience
out.ExpirationSeconds = (*int64)(unsafe.Pointer(in.ExpirationSeconds))
return nil
}
// Convert_v1beta1_TokenRequest_To_storage_TokenRequest is an autogenerated conversion function.
func Convert_v1beta1_TokenRequest_To_storage_TokenRequest(in *v1beta1.TokenRequest, out *storage.TokenRequest, s conversion.Scope) error {
return autoConvert_v1beta1_TokenRequest_To_storage_TokenRequest(in, out, s)
}
func autoConvert_storage_TokenRequest_To_v1beta1_TokenRequest(in *storage.TokenRequest, out *v1beta1.TokenRequest, s conversion.Scope) error {
out.Audience = in.Audience
out.ExpirationSeconds = (*int64)(unsafe.Pointer(in.ExpirationSeconds))
return nil
}
// Convert_storage_TokenRequest_To_v1beta1_TokenRequest is an autogenerated conversion function.
func Convert_storage_TokenRequest_To_v1beta1_TokenRequest(in *storage.TokenRequest, out *v1beta1.TokenRequest, s conversion.Scope) error {
return autoConvert_storage_TokenRequest_To_v1beta1_TokenRequest(in, out, s)
}
func autoConvert_v1beta1_VolumeAttachment_To_storage_VolumeAttachment(in *v1beta1.VolumeAttachment, out *storage.VolumeAttachment, s conversion.Scope) error { func autoConvert_v1beta1_VolumeAttachment_To_storage_VolumeAttachment(in *v1beta1.VolumeAttachment, out *storage.VolumeAttachment, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta out.ObjectMeta = in.ObjectMeta
if err := Convert_v1beta1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_v1beta1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(&in.Spec, &out.Spec, s); err != nil {

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"strings" "strings"
"time"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
@ -422,6 +423,7 @@ func validateCSIDriverSpec(
allErrs = append(allErrs, validatePodInfoOnMount(spec.PodInfoOnMount, fldPath.Child("podInfoOnMount"))...) allErrs = append(allErrs, validatePodInfoOnMount(spec.PodInfoOnMount, fldPath.Child("podInfoOnMount"))...)
allErrs = append(allErrs, validateStorageCapacity(spec.StorageCapacity, fldPath.Child("storageCapacity"))...) allErrs = append(allErrs, validateStorageCapacity(spec.StorageCapacity, fldPath.Child("storageCapacity"))...)
allErrs = append(allErrs, validateFSGroupPolicy(spec.FSGroupPolicy, fldPath.Child("fsGroupPolicy"))...) allErrs = append(allErrs, validateFSGroupPolicy(spec.FSGroupPolicy, fldPath.Child("fsGroupPolicy"))...)
allErrs = append(allErrs, validateTokenRequests(spec.TokenRequests, fldPath.Child("tokenRequests"))...)
allErrs = append(allErrs, validateVolumeLifecycleModes(spec.VolumeLifecycleModes, fldPath.Child("volumeLifecycleModes"))...) allErrs = append(allErrs, validateVolumeLifecycleModes(spec.VolumeLifecycleModes, fldPath.Child("volumeLifecycleModes"))...)
return allErrs return allErrs
} }
@ -473,6 +475,35 @@ func validateFSGroupPolicy(fsGroupPolicy *storage.FSGroupPolicy, fldPath *field.
return allErrs return allErrs
} }
// validateTokenRequests tests if the Audience in each TokenRequest are different.
// Besides, at most one TokenRequest can ignore Audience.
func validateTokenRequests(tokenRequests []storage.TokenRequest, fldPath *field.Path) field.ErrorList {
const min = 10 * time.Minute
allErrs := field.ErrorList{}
audiences := make(map[string]bool)
for i, tokenRequest := range tokenRequests {
path := fldPath.Index(i)
audience := tokenRequest.Audience
if _, ok := audiences[audience]; ok {
allErrs = append(allErrs, field.Duplicate(path.Child("audience"), audience))
continue
}
audiences[audience] = true
if tokenRequest.ExpirationSeconds == nil {
continue
}
if *tokenRequest.ExpirationSeconds < int64(min.Seconds()) {
allErrs = append(allErrs, field.Invalid(path.Child("expirationSeconds"), *tokenRequest.ExpirationSeconds, "may not specify a duration less than 10 minutes"))
}
if *tokenRequest.ExpirationSeconds > 1<<32 {
allErrs = append(allErrs, field.Invalid(path.Child("expirationSeconds"), *tokenRequest.ExpirationSeconds, "may not specify a duration larger than 2^32 seconds"))
}
}
return allErrs
}
// validateVolumeLifecycleModes tests if mode has one of the allowed values. // validateVolumeLifecycleModes tests if mode has one of the allowed values.
func validateVolumeLifecycleModes(modes []storage.VolumeLifecycleMode, fldPath *field.Path) field.ErrorList { func validateVolumeLifecycleModes(modes []storage.VolumeLifecycleMode, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}

View File

@ -1665,6 +1665,7 @@ func TestCSIDriverValidation(t *testing.T) {
attachNotRequired := false attachNotRequired := false
podInfoOnMount := true podInfoOnMount := true
notPodInfoOnMount := false notPodInfoOnMount := false
notRequiresRepublish := false
supportedFSGroupPolicy := storage.FileFSGroupPolicy supportedFSGroupPolicy := storage.FileFSGroupPolicy
invalidFSGroupPolicy := storage.ReadWriteOnceWithFSTypeFSGroupPolicy invalidFSGroupPolicy := storage.ReadWriteOnceWithFSTypeFSGroupPolicy
invalidFSGroupPolicy = "invalid-mode" invalidFSGroupPolicy = "invalid-mode"
@ -1672,68 +1673,77 @@ func TestCSIDriverValidation(t *testing.T) {
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &podInfoOnMount, PodInfoOnMount: &podInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
// driver name: dot only // driver name: dot only
ObjectMeta: metav1.ObjectMeta{Name: "io.kubernetes.storage.csi.driver"}, ObjectMeta: metav1.ObjectMeta{Name: "io.kubernetes.storage.csi.driver"},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &podInfoOnMount, PodInfoOnMount: &podInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
// driver name: dash only // driver name: dash only
ObjectMeta: metav1.ObjectMeta{Name: "io-kubernetes-storage-csi-driver"}, ObjectMeta: metav1.ObjectMeta{Name: "io-kubernetes-storage-csi-driver"},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
// driver name: numbers // driver name: numbers
ObjectMeta: metav1.ObjectMeta{Name: "1csi2driver3"}, ObjectMeta: metav1.ObjectMeta{Name: "1csi2driver3"},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &podInfoOnMount, PodInfoOnMount: &podInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
// driver name: dot and dash // driver name: dot and dash
ObjectMeta: metav1.ObjectMeta{Name: "io.kubernetes.storage.csi-driver"}, ObjectMeta: metav1.ObjectMeta{Name: "io.kubernetes.storage.csi-driver"},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &podInfoOnMount, PodInfoOnMount: &podInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &podInfoOnMount, PodInfoOnMount: &podInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,
}, },
@ -1742,8 +1752,9 @@ func TestCSIDriverValidation(t *testing.T) {
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecycleEphemeral, storage.VolumeLifecycleEphemeral,
}, },
@ -1752,8 +1763,9 @@ func TestCSIDriverValidation(t *testing.T) {
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecycleEphemeral, storage.VolumeLifecycleEphemeral,
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,
@ -1763,8 +1775,9 @@ func TestCSIDriverValidation(t *testing.T) {
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecycleEphemeral, storage.VolumeLifecycleEphemeral,
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,
@ -1775,9 +1788,10 @@ func TestCSIDriverValidation(t *testing.T) {
{ {
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
FSGroupPolicy: &supportedFSGroupPolicy, RequiresRepublish: &notRequiresRepublish,
FSGroupPolicy: &supportedFSGroupPolicy,
}, },
}, },
} }
@ -1855,11 +1869,13 @@ func TestCSIDriverValidationUpdate(t *testing.T) {
attachNotRequired := false attachNotRequired := false
podInfoOnMount := true podInfoOnMount := true
notPodInfoOnMount := false notPodInfoOnMount := false
notRequiresRepublish := false
old := storage.CSIDriver{ old := storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{Name: driverName}, ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecycleEphemeral, storage.VolumeLifecycleEphemeral,
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,
@ -2060,3 +2076,77 @@ func TestValidateCSIStorageCapacity(t *testing.T) {
} }
} }
func TestCSIServiceAccountToken(t *testing.T) {
driverName := "test-driver"
gcp := "gcp"
aws := "aws"
notRequiresRepublish := false
tests := []struct {
desc string
csiDriver *storage.CSIDriver
wantErr bool
}{
{
desc: "invalid - TokenRequests has tokens with the same audience",
csiDriver: &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{
TokenRequests: []storage.TokenRequest{{Audience: gcp}, {Audience: gcp}},
RequiresRepublish: &notRequiresRepublish,
},
},
wantErr: true,
},
{
desc: "invalid - TokenRequests has tokens with ExpirationSeconds less than 10min",
csiDriver: &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{
TokenRequests: []storage.TokenRequest{{Audience: gcp, ExpirationSeconds: utilpointer.Int64Ptr(10)}},
RequiresRepublish: &notRequiresRepublish,
},
},
wantErr: true,
},
{
desc: "invalid - TokenRequests has tokens with ExpirationSeconds less than 10min",
csiDriver: &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{
TokenRequests: []storage.TokenRequest{{Audience: gcp, ExpirationSeconds: utilpointer.Int64Ptr(1<<32 + 1)}},
RequiresRepublish: &notRequiresRepublish,
},
},
wantErr: true,
},
{
desc: "valid - TokenRequests has at most one token with empty string audience",
csiDriver: &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{
TokenRequests: []storage.TokenRequest{{Audience: ""}},
RequiresRepublish: &notRequiresRepublish,
},
},
},
{
desc: "valid - TokenRequests has tokens with different audience",
csiDriver: &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{
TokenRequests: []storage.TokenRequest{{}, {Audience: gcp}, {Audience: aws}},
RequiresRepublish: &notRequiresRepublish,
},
},
},
}
for _, test := range tests {
test.csiDriver.Spec.AttachRequired = new(bool)
test.csiDriver.Spec.PodInfoOnMount = new(bool)
if errs := ValidateCSIDriver(test.csiDriver); test.wantErr != (len(errs) != 0) {
t.Errorf("ValidateCSIDriver = %v, want err: %v", errs, test.wantErr)
}
}
}

View File

@ -114,6 +114,18 @@ func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) {
*out = new(bool) *out = new(bool)
**out = **in **out = **in
} }
if in.TokenRequests != nil {
in, out := &in.TokenRequests, &out.TokenRequests
*out = make([]TokenRequest, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.RequiresRepublish != nil {
in, out := &in.RequiresRepublish, &out.RequiresRepublish
*out = new(bool)
**out = **in
}
return return
} }
@ -398,6 +410,27 @@ func (in *StorageClassList) DeepCopyObject() runtime.Object {
return nil return nil
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenRequest) DeepCopyInto(out *TokenRequest) {
*out = *in
if in.ExpirationSeconds != nil {
in, out := &in.ExpirationSeconds, &out.ExpirationSeconds
*out = new(int64)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenRequest.
func (in *TokenRequest) DeepCopy() *TokenRequest {
if in == nil {
return nil
}
out := new(TokenRequest)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeAttachment) DeepCopyInto(out *VolumeAttachment) { func (in *VolumeAttachment) DeepCopyInto(out *VolumeAttachment) {
*out = *in *out = *in

View File

@ -21,7 +21,7 @@ import (
"sync" "sync"
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@ -272,7 +272,7 @@ func (plugin *TestPlugin) CanSupport(spec *volume.Spec) bool {
return true return true
} }
func (plugin *TestPlugin) RequiresRemount() bool { func (plugin *TestPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -43,6 +43,7 @@ import (
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
pvtesting "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/testing" pvtesting "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/testing"
pvutil "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util" pvutil "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util"
"k8s.io/kubernetes/pkg/volume"
vol "k8s.io/kubernetes/pkg/volume" vol "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/recyclerclient"
) )
@ -861,7 +862,7 @@ func (plugin *mockVolumePlugin) CanSupport(spec *vol.Spec) bool {
return true return true
} }
func (plugin *mockVolumePlugin) RequiresRemount() bool { func (plugin *mockVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -693,6 +693,13 @@ const (
// //
// Enable kubelet exec plugins for image pull credentials. // Enable kubelet exec plugins for image pull credentials.
KubeletCredentialProviders featuregate.Feature = "KubeletCredentialProviders" KubeletCredentialProviders featuregate.Feature = "KubeletCredentialProviders"
// owner: @zshihang
// alpha: v1.20
//
// Enable kubelet to pass pod's service account token to NodePublishVolume
// call of CSI driver which is mounting volumes for that pod.
CSIServiceAccountToken featuregate.Feature = "CSIServiceAccountToken"
) )
func init() { func init() {
@ -754,6 +761,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
CSIBlockVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.20 CSIBlockVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.20
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta}, CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
CSIStorageCapacity: {Default: false, PreRelease: featuregate.Alpha}, CSIStorageCapacity: {Default: false, PreRelease: featuregate.Alpha},
CSIServiceAccountToken: {Default: false, PreRelease: featuregate.Alpha},
GenericEphemeralVolume: {Default: false, PreRelease: featuregate.Alpha}, GenericEphemeralVolume: {Default: false, PreRelease: featuregate.Alpha},
CSIVolumeFSGroupPolicy: {Default: false, PreRelease: featuregate.Alpha}, CSIVolumeFSGroupPolicy: {Default: false, PreRelease: featuregate.Alpha},
RuntimeClass: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23 RuntimeClass: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23

View File

@ -557,7 +557,7 @@ func (asw *actualStateOfWorld) MarkRemountRequired(
continue continue
} }
if volumePlugin.RequiresRemount() { if volumePlugin.RequiresRemount(podObj.volumeSpec) {
podObj.remountRequired = true podObj.remountRequired = true
asw.attachedVolumes[volumeName].mountedPods[podName] = podObj asw.attachedVolumes[volumeName].mountedPods[podName] = podObj
} }

View File

@ -260,6 +260,11 @@ type volumeManager struct {
func (vm *volumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) { func (vm *volumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) {
defer runtime.HandleCrash() defer runtime.HandleCrash()
if vm.kubeClient != nil {
// start informer for CSIDriver
go vm.volumePluginMgr.Run(stopCh)
}
go vm.desiredStateOfWorldPopulator.Run(sourcesReady, stopCh) go vm.desiredStateOfWorldPopulator.Run(sourcesReady, stopCh)
klog.V(2).Infof("The desired_state_of_world populator starts") klog.V(2).Infof("The desired_state_of_world populator starts")
@ -268,11 +273,6 @@ func (vm *volumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan str
metrics.Register(vm.actualStateOfWorld, vm.desiredStateOfWorld, vm.volumePluginMgr) metrics.Register(vm.actualStateOfWorld, vm.desiredStateOfWorld, vm.volumePluginMgr)
if vm.kubeClient != nil {
// start informer for CSIDriver
vm.volumePluginMgr.Run(stopCh)
}
<-stopCh <-stopCh
klog.Infof("Shutting down Kubelet Volume Manager") klog.Infof("Shutting down Kubelet Volume Manager")
} }

View File

@ -520,6 +520,12 @@ func AddHandlers(h printers.PrintHandler) {
Name: "StorageCapacity", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["storageCapacity"], Name: "StorageCapacity", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["storageCapacity"],
}) })
} }
if utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, []metav1.TableColumnDefinition{
{Name: "TokenRequests", Type: "string", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["tokenRequests"]},
{Name: "RequiresRepublish", Type: "boolean", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["requiresRepublish"]},
}...)
}
csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, []metav1.TableColumnDefinition{ csiDriverColumnDefinitions = append(csiDriverColumnDefinitions, []metav1.TableColumnDefinition{
{Name: "Modes", Type: "string", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["volumeLifecycleModes"]}, {Name: "Modes", Type: "string", Description: storagev1.CSIDriverSpec{}.SwaggerDoc()["volumeLifecycleModes"]},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]}, {Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
@ -1395,6 +1401,21 @@ func printCSIDriver(obj *storage.CSIDriver, options printers.GenerateOptions) ([
} }
row.Cells = append(row.Cells, storageCapacity) row.Cells = append(row.Cells, storageCapacity)
} }
if utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
tokenRequests := "<unset>"
if obj.Spec.TokenRequests != nil {
audiences := []string{}
for _, t := range obj.Spec.TokenRequests {
audiences = append(audiences, t.Audience)
}
tokenRequests = strings.Join(audiences, ",")
}
requiresRepublish := false
if obj.Spec.RequiresRepublish != nil {
requiresRepublish = *obj.Spec.RequiresRepublish
}
row.Cells = append(row.Cells, tokenRequests, requiresRepublish)
}
row.Cells = append(row.Cells, modes, translateTimestampSince(obj.CreationTimestamp)) row.Cells = append(row.Cells, modes, translateTimestampSince(obj.CreationTimestamp))
return []metav1.TableRow{row}, nil return []metav1.TableRow{row}, nil
} }

View File

@ -48,13 +48,15 @@ func newStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) {
func validNewCSIDriver(name string) *storageapi.CSIDriver { func validNewCSIDriver(name string) *storageapi.CSIDriver {
attachRequired := true attachRequired := true
podInfoOnMount := true podInfoOnMount := true
requiresRepublish := true
return &storageapi.CSIDriver{ return &storageapi.CSIDriver{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: name,
}, },
Spec: storageapi.CSIDriverSpec{ Spec: storageapi.CSIDriverSpec{
AttachRequired: &attachRequired, AttachRequired: &attachRequired,
PodInfoOnMount: &podInfoOnMount, PodInfoOnMount: &podInfoOnMount,
RequiresRepublish: &requiresRepublish,
}, },
} }
} }
@ -68,6 +70,7 @@ func TestCreate(t *testing.T) {
csiDriver.ObjectMeta = metav1.ObjectMeta{GenerateName: "foo"} csiDriver.ObjectMeta = metav1.ObjectMeta{GenerateName: "foo"}
attachNotRequired := false attachNotRequired := false
notPodInfoOnMount := false notPodInfoOnMount := false
notRequiresRepublish := false
test.TestCreate( test.TestCreate(
// valid // valid
csiDriver, csiDriver,
@ -75,8 +78,9 @@ func TestCreate(t *testing.T) {
&storageapi.CSIDriver{ &storageapi.CSIDriver{
ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"},
Spec: storageapi.CSIDriverSpec{ Spec: storageapi.CSIDriverSpec{
AttachRequired: &attachNotRequired, AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount, PodInfoOnMount: &notPodInfoOnMount,
RequiresRepublish: &notRequiresRepublish,
}, },
}, },
) )

View File

@ -55,6 +55,10 @@ func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Objec
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIVolumeFSGroupPolicy) { if !utilfeature.DefaultFeatureGate.Enabled(features.CSIVolumeFSGroupPolicy) {
csiDriver.Spec.FSGroupPolicy = nil csiDriver.Spec.FSGroupPolicy = nil
} }
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
csiDriver.Spec.TokenRequests = nil
csiDriver.Spec.RequiresRepublish = nil
}
} }
func (csiDriverStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { func (csiDriverStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
@ -93,6 +97,17 @@ func (csiDriverStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.
newCSIDriver := obj.(*storage.CSIDriver) newCSIDriver := obj.(*storage.CSIDriver)
newCSIDriver.Spec.FSGroupPolicy = nil newCSIDriver.Spec.FSGroupPolicy = nil
} }
if old.(*storage.CSIDriver).Spec.TokenRequests == nil &&
!utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
csiDriver := obj.(*storage.CSIDriver)
csiDriver.Spec.TokenRequests = nil
}
if old.(*storage.CSIDriver).Spec.RequiresRepublish == nil &&
!utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
csiDriver := obj.(*storage.CSIDriver)
csiDriver.Spec.RequiresRepublish = nil
}
} }
func (csiDriverStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { func (csiDriverStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {

View File

@ -36,9 +36,10 @@ func getValidCSIDriver(name string) *storage.CSIDriver {
Name: name, Name: name,
}, },
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &enabled, AttachRequired: &enabled,
PodInfoOnMount: &enabled, PodInfoOnMount: &enabled,
StorageCapacity: &enabled, StorageCapacity: &enabled,
RequiresRepublish: &enabled,
}, },
} }
} }
@ -88,11 +89,13 @@ func TestCSIDriverPrepareForCreate(t *testing.T) {
attachRequired := true attachRequired := true
podInfoOnMount := true podInfoOnMount := true
storageCapacity := true storageCapacity := true
requiresRepublish := true
tests := []struct { tests := []struct {
name string name string
withCapacity bool withCapacity bool
withInline bool withInline bool
withServiceAccountToken bool
}{ }{
{ {
name: "inline enabled", name: "inline enabled",
@ -110,12 +113,21 @@ func TestCSIDriverPrepareForCreate(t *testing.T) {
name: "capacity disabled", name: "capacity disabled",
withCapacity: false, withCapacity: false,
}, },
{
name: "serviceAccountToken enabled",
withServiceAccountToken: true,
},
{
name: "serviceAccountToken disabled",
withServiceAccountToken: false,
},
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, test.withCapacity)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, test.withCapacity)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.withInline)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.withInline)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIServiceAccountToken, test.withServiceAccountToken)()
csiDriver := &storage.CSIDriver{ csiDriver := &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -128,6 +140,8 @@ func TestCSIDriverPrepareForCreate(t *testing.T) {
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,
}, },
TokenRequests: []storage.TokenRequest{},
RequiresRepublish: &requiresRepublish,
}, },
} }
Strategy.PrepareForCreate(ctx, csiDriver) Strategy.PrepareForCreate(ctx, csiDriver)
@ -153,6 +167,21 @@ func TestCSIDriverPrepareForCreate(t *testing.T) {
t.Errorf("VolumeLifecycleModes not stripped: %v", csiDriver.Spec) t.Errorf("VolumeLifecycleModes not stripped: %v", csiDriver.Spec)
} }
} }
if test.withServiceAccountToken {
if csiDriver.Spec.TokenRequests == nil {
t.Errorf("TokenRequests modified: %v", csiDriver.Spec)
}
if csiDriver.Spec.RequiresRepublish == nil {
t.Errorf("RequiresRepublish modified: %v", csiDriver.Spec)
}
} else {
if csiDriver.Spec.TokenRequests != nil {
t.Errorf("TokenRequests stripped: %v", csiDriver.Spec)
}
if csiDriver.Spec.RequiresRepublish != nil {
t.Errorf("RequiresRepublish stripped: %v", csiDriver.Spec)
}
}
}) })
} }
} }
@ -166,14 +195,10 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
attachRequired := true attachRequired := true
podInfoOnMount := true podInfoOnMount := true
driverWithoutModes := &storage.CSIDriver{ driverWithNothing := &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "foo", Name: "foo",
}, },
Spec: storage.CSIDriverSpec{
AttachRequired: &attachRequired,
PodInfoOnMount: &podInfoOnMount,
},
} }
driverWithPersistent := &storage.CSIDriver{ driverWithPersistent := &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -201,11 +226,8 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
} }
enabled := true enabled := true
disabled := false disabled := false
driverWithoutCapacity := &storage.CSIDriver{ gcp := "gcp"
ObjectMeta: metav1.ObjectMeta{ vault := "vault"
Name: "foo",
},
}
driverWithCapacityEnabled := &storage.CSIDriver{ driverWithCapacityEnabled := &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "foo", Name: "foo",
@ -222,116 +244,121 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
StorageCapacity: &disabled, StorageCapacity: &disabled,
}, },
} }
driverWithServiceAccountTokenGCP := &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: storage.CSIDriverSpec{
TokenRequests: []storage.TokenRequest{{Audience: gcp}},
RequiresRepublish: &enabled,
},
}
driverWithServiceAccountTokenVault := &storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: storage.CSIDriverSpec{
TokenRequests: []storage.TokenRequest{{Audience: vault}},
RequiresRepublish: &enabled,
},
}
var resultEmpty []storage.VolumeLifecycleMode
resultPersistent := []storage.VolumeLifecycleMode{storage.VolumeLifecyclePersistent} resultPersistent := []storage.VolumeLifecycleMode{storage.VolumeLifecyclePersistent}
resultEphemeral := []storage.VolumeLifecycleMode{storage.VolumeLifecycleEphemeral}
tests := []struct { tests := []struct {
name string name string
old, update *storage.CSIDriver old, update *storage.CSIDriver
withCapacity, withoutCapacity *bool csiStorageCapacityEnabled bool
withInline, withoutInline []storage.VolumeLifecycleMode csiInlineVolumeEnabled bool
csiServiceAccountTokenEnabled bool
wantCapacity *bool
wantModes []storage.VolumeLifecycleMode
wantTokenRequests []storage.TokenRequest
wantRequiresRepublish *bool
}{ }{
{ {
name: "before: no capacity, update: no capacity", name: "capacity feature enabled, before: none, update: enabled",
old: driverWithoutCapacity, csiStorageCapacityEnabled: true,
update: driverWithoutCapacity, old: driverWithNothing,
withCapacity: nil, update: driverWithCapacityEnabled,
withoutCapacity: nil, wantCapacity: &enabled,
}, },
{ {
name: "before: no capacity, update: enabled", name: "capacity feature disabled, before: none, update: disabled",
old: driverWithoutCapacity, old: driverWithNothing,
update: driverWithCapacityEnabled, update: driverWithCapacityDisabled,
withCapacity: &enabled, wantCapacity: nil,
withoutCapacity: nil,
}, },
{ {
name: "before: capacity enabled, update: disabled", name: "capacity feature disabled, before: enabled, update: disabled",
old: driverWithCapacityEnabled, old: driverWithCapacityEnabled,
update: driverWithCapacityDisabled, update: driverWithCapacityDisabled,
withCapacity: &disabled, wantCapacity: &disabled,
withoutCapacity: &disabled,
}, },
{ {
name: "before: capacity enabled, update: no capacity", name: "inline feature enabled, before: none, update: persitent",
old: driverWithCapacityEnabled, csiInlineVolumeEnabled: true,
update: driverWithoutCapacity, old: driverWithNothing,
withCapacity: nil, update: driverWithPersistent,
withoutCapacity: nil, wantModes: resultPersistent,
},
{
name: "before: no mode, update: no mode",
old: driverWithoutModes,
update: driverWithoutModes,
withInline: resultEmpty,
withoutInline: resultEmpty,
}, },
{ {
name: "before: no mode, update: persistent", name: "inline feature disabled, before: none, update: persitent",
old: driverWithoutModes, old: driverWithNothing,
update: driverWithPersistent, update: driverWithPersistent,
withInline: resultPersistent, wantModes: nil,
withoutInline: resultEmpty,
}, },
{ {
name: "before: persistent, update: ephemeral", name: "inline feature disabled, before: ephemeral, update: persitent",
old: driverWithPersistent, old: driverWithEphemeral,
update: driverWithEphemeral, update: driverWithPersistent,
withInline: resultEphemeral, wantModes: resultPersistent,
withoutInline: resultEphemeral,
}, },
{ {
name: "before: persistent, update: no mode", name: "service account token feature enabled, before: none, update: audience=gcp",
old: driverWithPersistent, csiServiceAccountTokenEnabled: true,
update: driverWithoutModes, old: driverWithNothing,
withInline: resultEmpty, update: driverWithServiceAccountTokenGCP,
withoutInline: resultEmpty, wantTokenRequests: []storage.TokenRequest{{Audience: gcp}},
wantRequiresRepublish: &enabled,
},
{
name: "service account token feature disabled, before: none, update: audience=gcp",
old: driverWithNothing,
update: driverWithServiceAccountTokenGCP,
wantTokenRequests: nil,
wantRequiresRepublish: nil,
},
{
name: "service account token feature disabled, before: audience=vault, update: audience=gcp",
old: driverWithServiceAccountTokenVault,
update: driverWithServiceAccountTokenGCP,
wantTokenRequests: []storage.TokenRequest{{Audience: gcp}},
wantRequiresRepublish: &enabled,
}, },
} }
runAll := func(t *testing.T, withCapacity, withInline bool) { for _, test := range tests {
for _, test := range tests { t.Run(test.name, func(t *testing.T) {
t.Run(test.name, func(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, test.csiStorageCapacityEnabled)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIStorageCapacity, withCapacity)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolumeEnabled)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, withInline)() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIServiceAccountToken, test.csiServiceAccountTokenEnabled)()
csiDriver := test.update.DeepCopy() csiDriver := test.update.DeepCopy()
Strategy.PrepareForUpdate(ctx, csiDriver, test.old) Strategy.PrepareForUpdate(ctx, csiDriver, test.old)
if withCapacity { require.Equal(t, test.wantCapacity, csiDriver.Spec.StorageCapacity)
require.Equal(t, test.withCapacity, csiDriver.Spec.StorageCapacity) require.Equal(t, test.wantModes, csiDriver.Spec.VolumeLifecycleModes)
} else { require.Equal(t, test.wantTokenRequests, csiDriver.Spec.TokenRequests)
require.Equal(t, test.withoutCapacity, csiDriver.Spec.StorageCapacity) require.Equal(t, test.wantRequiresRepublish, csiDriver.Spec.RequiresRepublish)
} })
if withInline {
require.Equal(t, test.withInline, csiDriver.Spec.VolumeLifecycleModes)
} else {
require.Equal(t, test.withoutInline, csiDriver.Spec.VolumeLifecycleModes)
}
})
}
} }
t.Run("with capacity", func(t *testing.T) {
runAll(t, true, false)
})
t.Run("without capacity", func(t *testing.T) {
runAll(t, false, false)
})
t.Run("with inline volumes", func(t *testing.T) {
runAll(t, false, true)
})
t.Run("without inline volumes", func(t *testing.T) {
runAll(t, false, false)
})
} }
func TestCSIDriverValidation(t *testing.T) { func TestCSIDriverValidation(t *testing.T) {
enabled := true enabled := true
disabled := true disabled := true
gcp := "gcp"
tests := []struct { tests := []struct {
name string name string
@ -350,9 +377,10 @@ func TestCSIDriverValidation(t *testing.T) {
Name: "foo", Name: "foo",
}, },
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &enabled, AttachRequired: &enabled,
PodInfoOnMount: &enabled, PodInfoOnMount: &enabled,
StorageCapacity: &enabled, StorageCapacity: &enabled,
RequiresRepublish: &enabled,
}, },
}, },
false, false,
@ -364,9 +392,10 @@ func TestCSIDriverValidation(t *testing.T) {
Name: "foo", Name: "foo",
}, },
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &disabled, AttachRequired: &disabled,
PodInfoOnMount: &disabled, PodInfoOnMount: &disabled,
StorageCapacity: &disabled, StorageCapacity: &disabled,
RequiresRepublish: &disabled,
}, },
}, },
false, false,
@ -378,9 +407,10 @@ func TestCSIDriverValidation(t *testing.T) {
Name: "*foo#", Name: "*foo#",
}, },
Spec: storage.CSIDriverSpec{ Spec: storage.CSIDriverSpec{
AttachRequired: &enabled, AttachRequired: &enabled,
PodInfoOnMount: &enabled, PodInfoOnMount: &enabled,
StorageCapacity: &enabled, StorageCapacity: &enabled,
RequiresRepublish: &enabled,
}, },
}, },
true, true,
@ -398,6 +428,7 @@ func TestCSIDriverValidation(t *testing.T) {
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecycleMode("no-such-mode"), storage.VolumeLifecycleMode("no-such-mode"),
}, },
RequiresRepublish: &enabled,
}, },
}, },
true, true,
@ -415,6 +446,7 @@ func TestCSIDriverValidation(t *testing.T) {
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,
}, },
RequiresRepublish: &enabled,
}, },
}, },
false, false,
@ -432,6 +464,7 @@ func TestCSIDriverValidation(t *testing.T) {
VolumeLifecycleModes: []storage.VolumeLifecycleMode{ VolumeLifecycleModes: []storage.VolumeLifecycleMode{
storage.VolumeLifecycleEphemeral, storage.VolumeLifecycleEphemeral,
}, },
RequiresRepublish: &enabled,
}, },
}, },
false, false,
@ -450,6 +483,23 @@ func TestCSIDriverValidation(t *testing.T) {
storage.VolumeLifecyclePersistent, storage.VolumeLifecyclePersistent,
storage.VolumeLifecycleEphemeral, storage.VolumeLifecycleEphemeral,
}, },
RequiresRepublish: &enabled,
},
},
false,
},
{
"service account token with gcp as audience",
&storage.CSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: storage.CSIDriverSpec{
AttachRequired: &enabled,
PodInfoOnMount: &enabled,
StorageCapacity: &enabled,
TokenRequests: []storage.TokenRequest{{Audience: gcp}},
RequiresRepublish: &enabled,
}, },
}, },
false, false,

View File

@ -87,7 +87,7 @@ func (plugin *awsElasticBlockStorePlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.AWSElasticBlockStore != nil) (spec.Volume != nil && spec.Volume.AWSElasticBlockStore != nil)
} }
func (plugin *awsElasticBlockStorePlugin) RequiresRemount() bool { func (plugin *awsElasticBlockStorePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -86,7 +86,7 @@ func (plugin *azureFilePlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.AzureFile != nil) (spec.Volume != nil && spec.Volume.AzureFile != nil)
} }
func (plugin *azureFilePlugin) RequiresRemount() bool { func (plugin *azureFilePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -121,7 +121,7 @@ func (plugin *azureDataDiskPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.AzureDisk != nil) (spec.Volume != nil && spec.Volume.AzureDisk != nil)
} }
func (plugin *azureDataDiskPlugin) RequiresRemount() bool { func (plugin *azureDataDiskPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -73,7 +73,7 @@ func (plugin *cephfsPlugin) CanSupport(spec *volume.Spec) bool {
return (spec.Volume != nil && spec.Volume.CephFS != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CephFS != nil) return (spec.Volume != nil && spec.Volume.CephFS != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CephFS != nil)
} }
func (plugin *cephfsPlugin) RequiresRemount() bool { func (plugin *cephfsPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -110,7 +110,7 @@ func (plugin *cinderPlugin) CanSupport(spec *volume.Spec) bool {
return (spec.Volume != nil && spec.Volume.Cinder != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Cinder != nil) return (spec.Volume != nil && spec.Volume.Cinder != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Cinder != nil)
} }
func (plugin *cinderPlugin) RequiresRemount() bool { func (plugin *cinderPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -78,7 +78,7 @@ func (plugin *configMapPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.ConfigMap != nil return spec.Volume != nil && spec.Volume.ConfigMap != nil
} }
func (plugin *configMapPlugin) RequiresRemount() bool { func (plugin *configMapPlugin) RequiresRemount(spec *volume.Spec) bool {
return true return true
} }

View File

@ -22,6 +22,7 @@ go_library(
"//pkg/volume/csi/nodeinfomanager:go_default_library", "//pkg/volume/csi/nodeinfomanager:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library", "//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/authentication/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/api/storage/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
@ -62,12 +63,16 @@ go_test(
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/authentication/v1:go_default_library",
"//pkg/apis/core/v1:go_default_library",
"//pkg/apis/storage/v1:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/csi/fake:go_default_library", "//pkg/volume/csi/fake:go_default_library",
"//pkg/volume/testing:go_default_library", "//pkg/volume/testing:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/types:go_default_library", "//pkg/volume/util/types:go_default_library",
"//staging/src/k8s.io/api/authentication/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/api/storage/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
@ -75,6 +80,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
@ -87,6 +93,7 @@ go_test(
"//staging/src/k8s.io/client-go/util/testing:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library", "//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/google.golang.org/grpc/codes:go_default_library", "//vendor/google.golang.org/grpc/codes:go_default_library",
"//vendor/google.golang.org/grpc/status:go_default_library", "//vendor/google.golang.org/grpc/status:go_default_library",

View File

@ -19,6 +19,7 @@ package csi
import ( import (
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"os" "os"
@ -27,6 +28,7 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
authenticationv1 "k8s.io/api/authentication/v1"
api "k8s.io/api/core/v1" api "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -224,14 +226,15 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error
if err != nil { if err != nil {
return volumetypes.NewTransientOperationFailure(log("mounter.SetUpAt failed to assemble volume attributes: %v", err)) return volumetypes.NewTransientOperationFailure(log("mounter.SetUpAt failed to assemble volume attributes: %v", err))
} }
if podAttrs != nil { volAttribs = mergeMap(volAttribs, podAttrs)
if volAttribs == nil {
volAttribs = podAttrs // Inject pod service account token into volume attributes
} else { if utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
for k, v := range podAttrs { serviceAccountTokenAttrs, err := c.podServiceAccountTokenAttrs()
volAttribs[k] = v if err != nil {
} return volumetypes.NewTransientOperationFailure(log("mounter.SetUpAt failed to get service accoount token attributes: %v", err))
} }
volAttribs = mergeMap(volAttribs, serviceAccountTokenAttrs)
} }
err = csi.NodePublishVolume( err = csi.NodePublishVolume(
@ -319,6 +322,57 @@ func (c *csiMountMgr) podAttributes() (map[string]string, error) {
return attrs, nil return attrs, nil
} }
func (c *csiMountMgr) podServiceAccountTokenAttrs() (map[string]string, error) {
if c.plugin.serviceAccountTokenGetter == nil {
return nil, errors.New("ServiceAccountTokenGetter is nil")
}
csiDriver, err := c.plugin.csiDriverLister.Get(string(c.driverName))
if err != nil {
if apierrors.IsNotFound(err) {
klog.V(5).Infof(log("CSIDriver %q not found, not adding service account token information", c.driverName))
return nil, nil
}
return nil, err
}
if len(csiDriver.Spec.TokenRequests) == 0 {
return nil, nil
}
outputs := map[string]authenticationv1.TokenRequestStatus{}
for _, tokenRequest := range csiDriver.Spec.TokenRequests {
audience := tokenRequest.Audience
audiences := []string{audience}
if audience == "" {
audiences = []string{}
}
tr, err := c.plugin.serviceAccountTokenGetter(c.pod.Namespace, c.pod.Spec.ServiceAccountName, &authenticationv1.TokenRequest{
Spec: authenticationv1.TokenRequestSpec{
Audiences: audiences,
ExpirationSeconds: tokenRequest.ExpirationSeconds,
BoundObjectRef: &authenticationv1.BoundObjectReference{
APIVersion: "v1",
Kind: "Pod",
Name: c.pod.Name,
UID: c.pod.UID,
},
},
})
if err != nil {
return nil, err
}
outputs[audience] = tr.Status
}
klog.V(4).Infof(log("Fetched service account token attrs for CSIDriver %q", c.driverName))
tokens, _ := json.Marshal(outputs)
return map[string]string{
"csi.storage.k8s.io/serviceAccount.tokens": string(tokens),
}, nil
}
func (c *csiMountMgr) GetAttributes() volume.Attributes { func (c *csiMountMgr) GetAttributes() volume.Attributes {
return volume.Attributes{ return volume.Attributes{
ReadOnly: c.readOnly, ReadOnly: c.readOnly,
@ -434,3 +488,13 @@ func makeVolumeHandle(podUID, volSourceSpecName string) string {
result := sha256.Sum256([]byte(fmt.Sprintf("%s%s", podUID, volSourceSpecName))) result := sha256.Sum256([]byte(fmt.Sprintf("%s%s", podUID, volSourceSpecName)))
return fmt.Sprintf("csi-%x", result) return fmt.Sprintf("csi-%x", result)
} }
func mergeMap(first, second map[string]string) map[string]string {
if first == nil && second != nil {
return second
}
for k, v := range second {
first[k] = v
}
return first
}

View File

@ -25,19 +25,29 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"testing" "testing"
"time"
"reflect" "reflect"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
authenticationv1 "k8s.io/api/authentication/v1"
api "k8s.io/api/core/v1" api "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
storagev1 "k8s.io/api/storage/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
fakeclient "k8s.io/client-go/kubernetes/fake" fakeclient "k8s.io/client-go/kubernetes/fake"
clitesting "k8s.io/client-go/testing"
featuregatetesting "k8s.io/component-base/featuregate/testing" featuregatetesting "k8s.io/component-base/featuregate/testing"
pkgauthenticationv1 "k8s.io/kubernetes/pkg/apis/authentication/v1"
pkgcorev1 "k8s.io/kubernetes/pkg/apis/core/v1"
pkgstoragev1 "k8s.io/kubernetes/pkg/apis/storage/v1"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
fakecsi "k8s.io/kubernetes/pkg/volume/csi/fake" fakecsi "k8s.io/kubernetes/pkg/volume/csi/fake"
@ -927,3 +937,122 @@ func TestIsCorruptedDir(t *testing.T) {
assert.Equal(t, test.expectedResult, isCorruptedDir, "TestCase[%d]: %s", i, test.desc) assert.Equal(t, test.expectedResult, isCorruptedDir, "TestCase[%d]: %s", i, test.desc)
} }
} }
func TestPodServiceAccountTokenAttrs(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIServiceAccountToken, true)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
scheme := runtime.NewScheme()
utilruntime.Must(pkgauthenticationv1.RegisterDefaults(scheme))
utilruntime.Must(pkgstoragev1.RegisterDefaults(scheme))
utilruntime.Must(pkgcorev1.RegisterDefaults(scheme))
gcp := "gcp"
tests := []struct {
desc string
driver *storagev1.CSIDriver
volumeContext map[string]string
wantVolumeContext map[string]string
}{
{
desc: "csi driver has no ServiceAccountToken",
driver: &storagev1.CSIDriver{
ObjectMeta: meta.ObjectMeta{
Name: testDriver,
},
Spec: storagev1.CSIDriverSpec{},
},
wantVolumeContext: nil,
},
{
desc: "one token with empty string as audience",
driver: &storagev1.CSIDriver{
ObjectMeta: meta.ObjectMeta{
Name: testDriver,
},
Spec: storagev1.CSIDriverSpec{
TokenRequests: []storagev1.TokenRequest{
{
Audience: "",
},
},
},
},
wantVolumeContext: map[string]string{"csi.storage.k8s.io/serviceAccount.tokens": `{"":{"token":"test-ns:test-service-account:3600:[api]","expirationTimestamp":"1970-01-01T00:00:01Z"}}`},
},
{
desc: "one token with non-empty string as audience",
driver: &storagev1.CSIDriver{
ObjectMeta: meta.ObjectMeta{
Name: testDriver,
},
Spec: storagev1.CSIDriverSpec{
TokenRequests: []storagev1.TokenRequest{
{
Audience: gcp,
},
},
},
},
wantVolumeContext: map[string]string{"csi.storage.k8s.io/serviceAccount.tokens": `{"gcp":{"token":"test-ns:test-service-account:3600:[gcp]","expirationTimestamp":"1970-01-01T00:00:01Z"}}`},
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
registerFakePlugin(testDriver, "endpoint", []string{"1.0.0"}, t)
client := fakeclient.NewSimpleClientset()
if test.driver != nil {
test.driver.Spec.VolumeLifecycleModes = []storage.VolumeLifecycleMode{
storage.VolumeLifecycleEphemeral,
storage.VolumeLifecyclePersistent,
}
scheme.Default(test.driver)
client = fakeclient.NewSimpleClientset(test.driver)
}
client.PrependReactor("create", "serviceaccounts", clitesting.ReactionFunc(func(action clitesting.Action) (bool, runtime.Object, error) {
tr := action.(clitesting.CreateAction).GetObject().(*authenticationv1.TokenRequest)
scheme.Default(tr)
if len(tr.Spec.Audiences) == 0 {
tr.Spec.Audiences = []string{"api"}
}
tr.Status.Token = fmt.Sprintf("%v:%v:%d:%v", action.GetNamespace(), testAccount, *tr.Spec.ExpirationSeconds, tr.Spec.Audiences)
tr.Status.ExpirationTimestamp = metav1.NewTime(time.Unix(1, 1))
return true, tr, nil
}))
plug, tmpDir := newTestPlugin(t, client)
defer os.RemoveAll(tmpDir)
mounter, err := plug.NewMounter(
volume.NewSpecFromVolume(makeTestVol("test", testDriver)),
&api.Pod{
ObjectMeta: meta.ObjectMeta{UID: testPodUID, Namespace: testns, Name: testPod},
Spec: api.PodSpec{
ServiceAccountName: testAccount,
},
},
volume.VolumeOptions{},
)
if err != nil {
t.Fatalf("Failed to create a csi mounter, err: %v", err)
}
csiMounter := mounter.(*csiMountMgr)
csiMounter.csiClient = setupClient(t, false)
if err := csiMounter.SetUp(volume.MounterArgs{}); err != nil {
t.Fatalf("mounter.Setup failed: %v", err)
}
pubs := csiMounter.csiClient.(*fakeCsiDriverClient).nodeClient.GetNodePublishedVolumes()
vol, ok := pubs[csiMounter.volumeID]
if !ok {
t.Error("csi server may not have received NodePublishVolume call")
}
if vol.Path != csiMounter.GetPath() {
t.Errorf("csi server expected path %s, got %s", csiMounter.GetPath(), vol.Path)
}
if diff := cmp.Diff(test.wantVolumeContext, vol.VolumeContext); diff != "" {
t.Errorf("podServiceAccountTokenAttrs() = diff (-want +got):\n%s", diff)
}
})
}
}

View File

@ -27,6 +27,7 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
authenticationv1 "k8s.io/api/authentication/v1"
api "k8s.io/api/core/v1" api "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -59,10 +60,11 @@ const (
) )
type csiPlugin struct { type csiPlugin struct {
host volume.VolumeHost host volume.VolumeHost
blockEnabled bool blockEnabled bool
csiDriverLister storagelisters.CSIDriverLister csiDriverLister storagelisters.CSIDriverLister
volumeAttachmentLister storagelisters.VolumeAttachmentLister serviceAccountTokenGetter func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error)
volumeAttachmentLister storagelisters.VolumeAttachmentLister
} }
// ProbeVolumePlugins returns implemented plugins // ProbeVolumePlugins returns implemented plugins
@ -205,6 +207,10 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error {
if p.csiDriverLister == nil { if p.csiDriverLister == nil {
klog.Error(log("CSIDriverLister not found on KubeletVolumeHost")) klog.Error(log("CSIDriverLister not found on KubeletVolumeHost"))
} }
p.serviceAccountTokenGetter = host.GetServiceAccountTokenFunc()
if p.serviceAccountTokenGetter == nil {
klog.Error(log("ServiceAccountTokenGetter not found on KubeletVolumeHost"))
}
// We don't run the volumeAttachmentLister in the kubelet context // We don't run the volumeAttachmentLister in the kubelet context
p.volumeAttachmentLister = nil p.volumeAttachmentLister = nil
} }
@ -334,8 +340,24 @@ func (p *csiPlugin) CanSupport(spec *volume.Spec) bool {
return spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil return spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CSI != nil
} }
func (p *csiPlugin) RequiresRemount() bool { func (p *csiPlugin) RequiresRemount(spec *volume.Spec) bool {
return false if !utilfeature.DefaultFeatureGate.Enabled(features.CSIServiceAccountToken) {
return false
}
if p.csiDriverLister == nil {
return false
}
driverName, err := GetCSIDriverName(spec)
if err != nil {
klog.V(5).Info(log("Failed to mark %q as republish required, err: %v", spec.Name(), err))
return false
}
csiDriver, err := p.csiDriverLister.Get(driverName)
if err != nil {
klog.V(5).Info(log("Failed to mark %q as republish required, err: %v", spec.Name(), err))
return false
}
return *csiDriver.Spec.RequiresRepublish
} }
func (p *csiPlugin) NewMounter( func (p *csiPlugin) NewMounter(

View File

@ -176,3 +176,20 @@ func getPVSourceFromSpec(spec *volume.Spec) (*api.CSIPersistentVolumeSource, err
func GetCSIMounterPath(path string) string { func GetCSIMounterPath(path string) string {
return filepath.Join(path, "/mount") return filepath.Join(path, "/mount")
} }
// GetCSIDriverName returns the csi driver name
func GetCSIDriverName(spec *volume.Spec) (string, error) {
volSrc, pvSrc, err := getSourceFromSpec(spec)
if err != nil {
return "", err
}
switch {
case volSrc != nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume):
return volSrc.Driver, nil
case pvSrc != nil:
return pvSrc.Driver, nil
default:
return "", errors.New(log("volume source not found in volume.Spec"))
}
}

View File

@ -80,7 +80,7 @@ func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.DownwardAPI != nil return spec.Volume != nil && spec.Volume.DownwardAPI != nil
} }
func (plugin *downwardAPIPlugin) RequiresRemount() bool { func (plugin *downwardAPIPlugin) RequiresRemount(spec *volume.Spec) bool {
return true return true
} }

View File

@ -94,7 +94,7 @@ func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool {
return false return false
} }
func (plugin *emptyDirPlugin) RequiresRemount() bool { func (plugin *emptyDirPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -86,7 +86,7 @@ func (plugin *fcPlugin) CanSupport(spec *volume.Spec) bool {
return (spec.Volume != nil && spec.Volume.FC != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FC != nil) return (spec.Volume != nil && spec.Volume.FC != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FC != nil)
} }
func (plugin *fcPlugin) RequiresRemount() bool { func (plugin *fcPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -148,7 +148,7 @@ func (plugin *flexVolumePlugin) CanSupport(spec *volume.Spec) bool {
} }
// RequiresRemount is part of the volume.VolumePlugin interface. // RequiresRemount is part of the volume.VolumePlugin interface.
func (plugin *flexVolumePlugin) RequiresRemount() bool { func (plugin *flexVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -108,7 +108,7 @@ func (p *flockerPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.Flocker != nil) (spec.Volume != nil && spec.Volume.Flocker != nil)
} }
func (p *flockerPlugin) RequiresRemount() bool { func (p *flockerPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -98,7 +98,7 @@ func (plugin *gcePersistentDiskPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil) (spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil)
} }
func (plugin *gcePersistentDiskPlugin) RequiresRemount() bool { func (plugin *gcePersistentDiskPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -77,7 +77,7 @@ func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.GitRepo != nil return spec.Volume != nil && spec.Volume.GitRepo != nil
} }
func (plugin *gitRepoPlugin) RequiresRemount() bool { func (plugin *gitRepoPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -120,7 +120,7 @@ func (plugin *glusterfsPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.Glusterfs != nil) (spec.Volume != nil && spec.Volume.Glusterfs != nil)
} }
func (plugin *glusterfsPlugin) RequiresRemount() bool { func (plugin *glusterfsPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -85,7 +85,7 @@ func (plugin *hostPathPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.HostPath != nil) (spec.Volume != nil && spec.Volume.HostPath != nil)
} }
func (plugin *hostPathPlugin) RequiresRemount() bool { func (plugin *hostPathPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -79,7 +79,7 @@ func (plugin *iscsiPlugin) CanSupport(spec *volume.Spec) bool {
return (spec.Volume != nil && spec.Volume.ISCSI != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.ISCSI != nil) return (spec.Volume != nil && spec.Volume.ISCSI != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.ISCSI != nil)
} }
func (plugin *iscsiPlugin) RequiresRemount() bool { func (plugin *iscsiPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -83,7 +83,7 @@ func (plugin *localVolumePlugin) CanSupport(spec *volume.Spec) bool {
return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Local != nil) return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Local != nil)
} }
func (plugin *localVolumePlugin) RequiresRemount() bool { func (plugin *localVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -90,7 +90,7 @@ func (plugin *nfsPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.NFS != nil) (spec.Volume != nil && spec.Volume.NFS != nil)
} }
func (plugin *nfsPlugin) RequiresRemount() bool { func (plugin *nfsPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -17,7 +17,7 @@ limitations under the License.
package volume package volume
import ( import (
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
) )
@ -48,7 +48,7 @@ func (n *noopExpandableVolumePluginInstance) CanSupport(spec *Spec) bool {
return true return true
} }
func (n *noopExpandableVolumePluginInstance) RequiresRemount() bool { func (n *noopExpandableVolumePluginInstance) RequiresRemount(spec *Spec) bool {
return false return false
} }

View File

@ -163,7 +163,7 @@ type VolumePlugin interface {
// RequiresRemount returns true if this plugin requires mount calls to be // RequiresRemount returns true if this plugin requires mount calls to be
// reexecuted. Atomically updating volumes, like Downward API, depend on // reexecuted. Atomically updating volumes, like Downward API, depend on
// this to update the contents of the volume. // this to update the contents of the volume.
RequiresRemount() bool RequiresRemount(spec *Spec) bool
// NewMounter creates a new volume.Mounter from an API specification. // NewMounter creates a new volume.Mounter from an API specification.
// Ownership of the spec pointer in *not* transferred. // Ownership of the spec pointer in *not* transferred.
@ -1027,6 +1027,7 @@ func (pm *VolumePluginMgr) Run(stopCh <-chan struct{}) {
// start informer for CSIDriver // start informer for CSIDriver
informerFactory := kletHost.GetInformerFactory() informerFactory := kletHost.GetInformerFactory()
informerFactory.Start(stopCh) informerFactory.Start(stopCh)
informerFactory.WaitForCacheSync(stopCh)
} }
} }

View File

@ -19,7 +19,7 @@ package volume
import ( import (
"testing" "testing"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
) )
@ -75,7 +75,7 @@ func (plugin *testPlugins) CanSupport(spec *Spec) bool {
return true return true
} }
func (plugin *testPlugins) RequiresRemount() bool { func (plugin *testPlugins) RequiresRemount(spec *Spec) bool {
return false return false
} }

View File

@ -96,7 +96,7 @@ func (plugin *portworxVolumePlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.PortworxVolume != nil) (spec.Volume != nil && spec.Volume.PortworxVolume != nil)
} }
func (plugin *portworxVolumePlugin) RequiresRemount() bool { func (plugin *portworxVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -93,7 +93,7 @@ func (plugin *projectedPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.Projected != nil return spec.Volume != nil && spec.Volume.Projected != nil
} }
func (plugin *projectedPlugin) RequiresRemount() bool { func (plugin *projectedPlugin) RequiresRemount(spec *volume.Spec) bool {
return true return true
} }

View File

@ -116,7 +116,7 @@ func (plugin *quobytePlugin) CanSupport(spec *volume.Spec) bool {
return false return false
} }
func (plugin *quobytePlugin) RequiresRemount() bool { func (plugin *quobytePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -107,7 +107,7 @@ func (plugin *rbdPlugin) CanSupport(spec *volume.Spec) bool {
return (spec.Volume != nil && spec.Volume.RBD != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.RBD != nil) return (spec.Volume != nil && spec.Volume.RBD != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.RBD != nil)
} }
func (plugin *rbdPlugin) RequiresRemount() bool { func (plugin *rbdPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -679,7 +679,7 @@ func TestRequiresRemount(t *testing.T) {
plugMgr := volume.VolumePluginMgr{} plugMgr := volume.VolumePluginMgr{}
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)) plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil))
plug, _ := plugMgr.FindPluginByName("kubernetes.io/rbd") plug, _ := plugMgr.FindPluginByName("kubernetes.io/rbd")
has := plug.RequiresRemount() has := plug.RequiresRemount(nil)
if has { if has {
t.Errorf("Exepcted RequiresRemount to be false, got %t", has) t.Errorf("Exepcted RequiresRemount to be false, got %t", has)
} }

View File

@ -72,7 +72,7 @@ func (p *sioPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.ScaleIO != nil) (spec.Volume != nil && spec.Volume.ScaleIO != nil)
} }
func (p *sioPlugin) RequiresRemount() bool { func (p *sioPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -81,7 +81,7 @@ func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool {
return spec.Volume != nil && spec.Volume.Secret != nil return spec.Volume != nil && spec.Volume.Secret != nil
} }
func (plugin *secretPlugin) RequiresRemount() bool { func (plugin *secretPlugin) RequiresRemount(spec *volume.Spec) bool {
return true return true
} }

View File

@ -92,7 +92,7 @@ func (plugin *storageosPlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.StorageOS != nil) (spec.Volume != nil && spec.Volume.StorageOS != nil)
} }
func (plugin *storageosPlugin) RequiresRemount() bool { func (plugin *storageosPlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -47,6 +47,7 @@ import (
utiltesting "k8s.io/client-go/util/testing" utiltesting "k8s.io/client-go/util/testing"
cloudprovider "k8s.io/cloud-provider" cloudprovider "k8s.io/cloud-provider"
proxyutil "k8s.io/kubernetes/pkg/proxy/util" proxyutil "k8s.io/kubernetes/pkg/proxy/util"
"k8s.io/kubernetes/pkg/volume"
. "k8s.io/kubernetes/pkg/volume" . "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/hostutil"
@ -467,7 +468,7 @@ func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool {
return true return true
} }
func (plugin *FakeVolumePlugin) RequiresRemount() bool { func (plugin *FakeVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return plugin.SupportsRemount return plugin.SupportsRemount
} }
@ -724,8 +725,8 @@ func (f *FakeBasicVolumePlugin) NewUnmounter(volName string, podUID types.UID) (
return f.Plugin.NewUnmounter(volName, podUID) return f.Plugin.NewUnmounter(volName, podUID)
} }
func (f *FakeBasicVolumePlugin) RequiresRemount() bool { func (f *FakeBasicVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return f.Plugin.RequiresRemount() return f.Plugin.RequiresRemount(spec)
} }
func (f *FakeBasicVolumePlugin) SupportsBulkVolumeVerification() bool { func (f *FakeBasicVolumePlugin) SupportsBulkVolumeVerification() bool {
@ -801,7 +802,7 @@ func (plugin *FakeFileVolumePlugin) CanSupport(spec *Spec) bool {
return true return true
} }
func (plugin *FakeFileVolumePlugin) RequiresRemount() bool { func (plugin *FakeFileVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -92,7 +92,7 @@ func (plugin *vsphereVolumePlugin) CanSupport(spec *volume.Spec) bool {
(spec.Volume != nil && spec.Volume.VsphereVolume != nil) (spec.Volume != nil && spec.Volume.VsphereVolume != nil)
} }
func (plugin *vsphereVolumePlugin) RequiresRemount() bool { func (plugin *vsphereVolumePlugin) RequiresRemount(spec *volume.Spec) bool {
return false return false
} }

View File

@ -298,10 +298,38 @@ func (m *StorageClassList) XXX_DiscardUnknown() {
var xxx_messageInfo_StorageClassList proto.InternalMessageInfo var xxx_messageInfo_StorageClassList proto.InternalMessageInfo
func (m *TokenRequest) Reset() { *m = TokenRequest{} }
func (*TokenRequest) ProtoMessage() {}
func (*TokenRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{9}
}
func (m *TokenRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TokenRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
func (m *TokenRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_TokenRequest.Merge(m, src)
}
func (m *TokenRequest) XXX_Size() int {
return m.Size()
}
func (m *TokenRequest) XXX_DiscardUnknown() {
xxx_messageInfo_TokenRequest.DiscardUnknown(m)
}
var xxx_messageInfo_TokenRequest proto.InternalMessageInfo
func (m *VolumeAttachment) Reset() { *m = VolumeAttachment{} } func (m *VolumeAttachment) Reset() { *m = VolumeAttachment{} }
func (*VolumeAttachment) ProtoMessage() {} func (*VolumeAttachment) ProtoMessage() {}
func (*VolumeAttachment) Descriptor() ([]byte, []int) { func (*VolumeAttachment) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{9} return fileDescriptor_3b530c1983504d8d, []int{10}
} }
func (m *VolumeAttachment) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachment) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -329,7 +357,7 @@ var xxx_messageInfo_VolumeAttachment proto.InternalMessageInfo
func (m *VolumeAttachmentList) Reset() { *m = VolumeAttachmentList{} } func (m *VolumeAttachmentList) Reset() { *m = VolumeAttachmentList{} }
func (*VolumeAttachmentList) ProtoMessage() {} func (*VolumeAttachmentList) ProtoMessage() {}
func (*VolumeAttachmentList) Descriptor() ([]byte, []int) { func (*VolumeAttachmentList) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{10} return fileDescriptor_3b530c1983504d8d, []int{11}
} }
func (m *VolumeAttachmentList) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentList) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -357,7 +385,7 @@ var xxx_messageInfo_VolumeAttachmentList proto.InternalMessageInfo
func (m *VolumeAttachmentSource) Reset() { *m = VolumeAttachmentSource{} } func (m *VolumeAttachmentSource) Reset() { *m = VolumeAttachmentSource{} }
func (*VolumeAttachmentSource) ProtoMessage() {} func (*VolumeAttachmentSource) ProtoMessage() {}
func (*VolumeAttachmentSource) Descriptor() ([]byte, []int) { func (*VolumeAttachmentSource) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{11} return fileDescriptor_3b530c1983504d8d, []int{12}
} }
func (m *VolumeAttachmentSource) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentSource) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -385,7 +413,7 @@ var xxx_messageInfo_VolumeAttachmentSource proto.InternalMessageInfo
func (m *VolumeAttachmentSpec) Reset() { *m = VolumeAttachmentSpec{} } func (m *VolumeAttachmentSpec) Reset() { *m = VolumeAttachmentSpec{} }
func (*VolumeAttachmentSpec) ProtoMessage() {} func (*VolumeAttachmentSpec) ProtoMessage() {}
func (*VolumeAttachmentSpec) Descriptor() ([]byte, []int) { func (*VolumeAttachmentSpec) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{12} return fileDescriptor_3b530c1983504d8d, []int{13}
} }
func (m *VolumeAttachmentSpec) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentSpec) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -413,7 +441,7 @@ var xxx_messageInfo_VolumeAttachmentSpec proto.InternalMessageInfo
func (m *VolumeAttachmentStatus) Reset() { *m = VolumeAttachmentStatus{} } func (m *VolumeAttachmentStatus) Reset() { *m = VolumeAttachmentStatus{} }
func (*VolumeAttachmentStatus) ProtoMessage() {} func (*VolumeAttachmentStatus) ProtoMessage() {}
func (*VolumeAttachmentStatus) Descriptor() ([]byte, []int) { func (*VolumeAttachmentStatus) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{13} return fileDescriptor_3b530c1983504d8d, []int{14}
} }
func (m *VolumeAttachmentStatus) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentStatus) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -441,7 +469,7 @@ var xxx_messageInfo_VolumeAttachmentStatus proto.InternalMessageInfo
func (m *VolumeError) Reset() { *m = VolumeError{} } func (m *VolumeError) Reset() { *m = VolumeError{} }
func (*VolumeError) ProtoMessage() {} func (*VolumeError) ProtoMessage() {}
func (*VolumeError) Descriptor() ([]byte, []int) { func (*VolumeError) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{14} return fileDescriptor_3b530c1983504d8d, []int{15}
} }
func (m *VolumeError) XXX_Unmarshal(b []byte) error { func (m *VolumeError) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -469,7 +497,7 @@ var xxx_messageInfo_VolumeError proto.InternalMessageInfo
func (m *VolumeNodeResources) Reset() { *m = VolumeNodeResources{} } func (m *VolumeNodeResources) Reset() { *m = VolumeNodeResources{} }
func (*VolumeNodeResources) ProtoMessage() {} func (*VolumeNodeResources) ProtoMessage() {}
func (*VolumeNodeResources) Descriptor() ([]byte, []int) { func (*VolumeNodeResources) Descriptor() ([]byte, []int) {
return fileDescriptor_3b530c1983504d8d, []int{15} return fileDescriptor_3b530c1983504d8d, []int{16}
} }
func (m *VolumeNodeResources) XXX_Unmarshal(b []byte) error { func (m *VolumeNodeResources) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -505,6 +533,7 @@ func init() {
proto.RegisterType((*StorageClass)(nil), "k8s.io.api.storage.v1.StorageClass") proto.RegisterType((*StorageClass)(nil), "k8s.io.api.storage.v1.StorageClass")
proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.storage.v1.StorageClass.ParametersEntry") proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.storage.v1.StorageClass.ParametersEntry")
proto.RegisterType((*StorageClassList)(nil), "k8s.io.api.storage.v1.StorageClassList") proto.RegisterType((*StorageClassList)(nil), "k8s.io.api.storage.v1.StorageClassList")
proto.RegisterType((*TokenRequest)(nil), "k8s.io.api.storage.v1.TokenRequest")
proto.RegisterType((*VolumeAttachment)(nil), "k8s.io.api.storage.v1.VolumeAttachment") proto.RegisterType((*VolumeAttachment)(nil), "k8s.io.api.storage.v1.VolumeAttachment")
proto.RegisterType((*VolumeAttachmentList)(nil), "k8s.io.api.storage.v1.VolumeAttachmentList") proto.RegisterType((*VolumeAttachmentList)(nil), "k8s.io.api.storage.v1.VolumeAttachmentList")
proto.RegisterType((*VolumeAttachmentSource)(nil), "k8s.io.api.storage.v1.VolumeAttachmentSource") proto.RegisterType((*VolumeAttachmentSource)(nil), "k8s.io.api.storage.v1.VolumeAttachmentSource")
@ -520,95 +549,101 @@ func init() {
} }
var fileDescriptor_3b530c1983504d8d = []byte{ var fileDescriptor_3b530c1983504d8d = []byte{
// 1395 bytes of a gzipped FileDescriptorProto // 1500 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0x1b, 0xc5,
0x17, 0xcf, 0xc6, 0x76, 0x7e, 0x8c, 0x93, 0xc6, 0x99, 0xe4, 0xfb, 0xfd, 0xfa, 0x9b, 0x83, 0x37, 0x17, 0xcf, 0xc6, 0xce, 0xaf, 0x71, 0xd2, 0x24, 0x93, 0xf4, 0xfb, 0x35, 0x39, 0xd8, 0xd1, 0xb6,
0x5a, 0x2a, 0x08, 0x85, 0xae, 0x9b, 0x52, 0xaa, 0xaa, 0x52, 0x91, 0xe2, 0xc4, 0xa5, 0x11, 0x71, 0x82, 0x50, 0xe8, 0xba, 0x29, 0xa5, 0xaa, 0x2a, 0x15, 0x29, 0x9b, 0xb8, 0x34, 0x22, 0xbf, 0x34,
0x12, 0x8d, 0x4b, 0x85, 0x10, 0x20, 0x26, 0xbb, 0x13, 0x67, 0x1b, 0xef, 0xce, 0x76, 0x77, 0x6c, 0x0e, 0x15, 0x42, 0x80, 0x3a, 0xd9, 0x9d, 0x38, 0x5b, 0x7b, 0x77, 0xb6, 0x3b, 0x63, 0x53, 0xdf,
0xf0, 0x8d, 0x13, 0x37, 0x24, 0xb8, 0xf2, 0x57, 0x80, 0x04, 0x17, 0x8e, 0x9c, 0xca, 0xad, 0xe2, 0xe0, 0xc2, 0x0d, 0x09, 0xae, 0x88, 0x3f, 0x02, 0x24, 0xb8, 0x70, 0xe4, 0x54, 0x6e, 0x15, 0xa7,
0xd4, 0xd3, 0x8a, 0x2e, 0x67, 0xb8, 0x71, 0xc9, 0x09, 0xcd, 0xec, 0xd8, 0xfb, 0xc3, 0xeb, 0x34, 0x9e, 0x2c, 0x6a, 0xce, 0xf0, 0x07, 0xe4, 0x84, 0x66, 0x76, 0xec, 0xfd, 0xe1, 0x75, 0x9a, 0x5e,
0xbd, 0xe4, 0xe6, 0x79, 0xef, 0x7d, 0x3e, 0xef, 0xbd, 0x79, 0x3f, 0x66, 0x0d, 0xde, 0x3b, 0xbd, 0x72, 0xf3, 0xbe, 0x1f, 0x9f, 0xf7, 0x66, 0xde, 0x7b, 0x9f, 0x37, 0x06, 0x1f, 0x34, 0xee, 0x30,
0xe3, 0xeb, 0x16, 0xad, 0x9f, 0xf6, 0x8e, 0x88, 0xe7, 0x10, 0x46, 0xfc, 0x7a, 0x9f, 0x38, 0x26, 0xc3, 0xa1, 0x95, 0x46, 0xeb, 0x88, 0x04, 0x1e, 0xe1, 0x84, 0x55, 0xda, 0xc4, 0xb3, 0x69, 0x50,
0xf5, 0xea, 0x52, 0x81, 0x5d, 0xab, 0xee, 0x33, 0xea, 0xe1, 0x0e, 0xa9, 0xf7, 0x37, 0xeb, 0x1d, 0x51, 0x0a, 0xec, 0x3b, 0x15, 0xc6, 0x69, 0x80, 0xeb, 0xa4, 0xd2, 0x5e, 0xaf, 0xd4, 0x89, 0x47,
0xe2, 0x10, 0x0f, 0x33, 0x62, 0xea, 0xae, 0x47, 0x19, 0x85, 0xff, 0x89, 0xcc, 0x74, 0xec, 0x5a, 0x02, 0xcc, 0x89, 0x6d, 0xf8, 0x01, 0xe5, 0x14, 0x5e, 0x0e, 0xcd, 0x0c, 0xec, 0x3b, 0x86, 0x32,
0xba, 0x34, 0xd3, 0xfb, 0x9b, 0x6b, 0xd7, 0x3b, 0x16, 0x3b, 0xe9, 0x1d, 0xe9, 0x06, 0xb5, 0xeb, 0x33, 0xda, 0xeb, 0x2b, 0xd7, 0xeb, 0x0e, 0x3f, 0x69, 0x1d, 0x19, 0x16, 0x75, 0x2b, 0x75, 0x5a,
0x1d, 0xda, 0xa1, 0x75, 0x61, 0x7d, 0xd4, 0x3b, 0x16, 0x27, 0x71, 0x10, 0xbf, 0x22, 0x96, 0x35, 0xa7, 0x15, 0x69, 0x7d, 0xd4, 0x3a, 0x96, 0x5f, 0xf2, 0x43, 0xfe, 0x0a, 0x51, 0x56, 0xf4, 0x58,
0x2d, 0xe1, 0xcc, 0xa0, 0x5e, 0x9e, 0xa7, 0xb5, 0x5b, 0xb1, 0x8d, 0x8d, 0x8d, 0x13, 0xcb, 0x21, 0x30, 0x8b, 0x06, 0x59, 0x91, 0x56, 0x6e, 0x45, 0x36, 0x2e, 0xb6, 0x4e, 0x1c, 0x8f, 0x04, 0x9d,
0xde, 0xa0, 0xee, 0x9e, 0x76, 0xb8, 0xc0, 0xaf, 0xdb, 0x84, 0xe1, 0x3c, 0x54, 0x7d, 0x12, 0xca, 0x8a, 0xdf, 0xa8, 0x0b, 0x01, 0xab, 0xb8, 0x84, 0xe3, 0x2c, 0xaf, 0xca, 0x28, 0xaf, 0xa0, 0xe5,
0xeb, 0x39, 0xcc, 0xb2, 0xc9, 0x18, 0xe0, 0xf6, 0xcb, 0x00, 0xbe, 0x71, 0x42, 0x6c, 0x9c, 0xc5, 0x71, 0xc7, 0x25, 0x43, 0x0e, 0xb7, 0x5f, 0xe5, 0xc0, 0xac, 0x13, 0xe2, 0xe2, 0xb4, 0x9f, 0xfe,
0x69, 0x3f, 0x2b, 0x60, 0x7e, 0xbb, 0xbd, 0xbb, 0xe3, 0x59, 0x7d, 0xe2, 0xc1, 0xcf, 0xc1, 0x1c, 0xab, 0x06, 0x66, 0x36, 0x6b, 0xdb, 0x5b, 0x81, 0xd3, 0x26, 0x01, 0x7c, 0x04, 0xa6, 0x45, 0x46,
0x8f, 0xc8, 0xc4, 0x0c, 0x57, 0x95, 0x75, 0x65, 0xa3, 0x7c, 0xf3, 0x86, 0x1e, 0xdf, 0xd4, 0x88, 0x36, 0xe6, 0xb8, 0xa8, 0xad, 0x6a, 0x6b, 0x85, 0x9b, 0x37, 0x8c, 0xe8, 0xa6, 0x06, 0xc0, 0x86,
0x58, 0x77, 0x4f, 0x3b, 0x5c, 0xe0, 0xeb, 0xdc, 0x5a, 0xef, 0x6f, 0xea, 0x07, 0x47, 0x8f, 0x89, 0xdf, 0xa8, 0x0b, 0x01, 0x33, 0x84, 0xb5, 0xd1, 0x5e, 0x37, 0xf6, 0x8f, 0x1e, 0x13, 0x8b, 0xef,
0xc1, 0x5a, 0x84, 0xe1, 0x06, 0x7c, 0x1a, 0xa8, 0x53, 0x61, 0xa0, 0x82, 0x58, 0x86, 0x46, 0xac, 0x12, 0x8e, 0x4d, 0xf8, 0xac, 0x5b, 0x1e, 0xeb, 0x75, 0xcb, 0x20, 0x92, 0xa1, 0x01, 0x2a, 0xbc,
0xf0, 0x3e, 0x28, 0xfa, 0x2e, 0x31, 0xaa, 0xd3, 0x82, 0xfd, 0xaa, 0x9e, 0x5b, 0x07, 0x7d, 0x14, 0x0f, 0xf2, 0xcc, 0x27, 0x56, 0x71, 0x5c, 0xa2, 0x5f, 0x35, 0x32, 0xeb, 0x60, 0x0c, 0x32, 0xaa,
0x51, 0xdb, 0x25, 0x46, 0x63, 0x41, 0x32, 0x16, 0xf9, 0x09, 0x09, 0xbc, 0xf6, 0x93, 0x02, 0x16, 0xf9, 0xc4, 0x32, 0x67, 0x15, 0x62, 0x5e, 0x7c, 0x21, 0xe9, 0xaf, 0xff, 0xa2, 0x81, 0xb9, 0x81,
0x47, 0x56, 0x7b, 0x96, 0xcf, 0xe0, 0x27, 0x63, 0xb1, 0xeb, 0x17, 0x8b, 0x9d, 0xa3, 0x45, 0xe4, 0xd5, 0x8e, 0xc3, 0x38, 0xfc, 0x6c, 0x28, 0x77, 0xe3, 0x7c, 0xb9, 0x0b, 0x6f, 0x99, 0xf9, 0x82,
0x15, 0xe9, 0x67, 0x6e, 0x28, 0x49, 0xc4, 0xdd, 0x04, 0x25, 0x8b, 0x11, 0xdb, 0xaf, 0x4e, 0xaf, 0x8a, 0x33, 0xdd, 0x97, 0xc4, 0xf2, 0xae, 0x82, 0x09, 0x87, 0x13, 0x97, 0x15, 0xc7, 0x57, 0x73,
0x17, 0x36, 0xca, 0x37, 0xd7, 0x5f, 0x16, 0x78, 0x63, 0x51, 0x92, 0x95, 0x76, 0x39, 0x0c, 0x45, 0x6b, 0x85, 0x9b, 0xab, 0xaf, 0x4a, 0xdc, 0x9c, 0x53, 0x60, 0x13, 0xdb, 0xc2, 0x0d, 0x85, 0xde,
0x68, 0xed, 0x9f, 0xe9, 0x44, 0xd8, 0x3c, 0x1d, 0x78, 0x17, 0x5c, 0xc1, 0x8c, 0x61, 0xe3, 0x04, 0xfa, 0x8f, 0xf9, 0x58, 0xda, 0xe2, 0x38, 0xf0, 0x2e, 0xb8, 0x84, 0x39, 0xc7, 0xd6, 0x09, 0x22,
0x91, 0x27, 0x3d, 0xcb, 0x23, 0xa6, 0x08, 0x7e, 0xae, 0x01, 0xc3, 0x40, 0xbd, 0xb2, 0x95, 0xd2, 0x4f, 0x5a, 0x4e, 0x40, 0x6c, 0x99, 0xfc, 0xb4, 0x09, 0x7b, 0xdd, 0xf2, 0xa5, 0x8d, 0x84, 0x06,
0xa0, 0x8c, 0x25, 0xc7, 0xba, 0xd4, 0xdc, 0x75, 0x8e, 0xe9, 0x81, 0xd3, 0xa2, 0x3d, 0x87, 0x89, 0xa5, 0x2c, 0x85, 0xaf, 0x4f, 0xed, 0x6d, 0xef, 0x98, 0xee, 0x7b, 0xbb, 0xb4, 0xe5, 0x71, 0x79,
0x6b, 0x95, 0xd8, 0xc3, 0x94, 0x06, 0x65, 0x2c, 0xa1, 0x01, 0x56, 0xfb, 0xb4, 0xdb, 0xb3, 0xc9, 0xad, 0xca, 0xf7, 0x20, 0xa1, 0x41, 0x29, 0x4b, 0x68, 0x81, 0xe5, 0x36, 0x6d, 0xb6, 0x5c, 0xb2,
0x9e, 0x75, 0x4c, 0x8c, 0x81, 0xd1, 0x25, 0x2d, 0x6a, 0x12, 0xbf, 0x5a, 0x58, 0x2f, 0x6c, 0xcc, 0xe3, 0x1c, 0x13, 0xab, 0x63, 0x35, 0xc9, 0x2e, 0xb5, 0x09, 0x2b, 0xe6, 0x56, 0x73, 0x6b, 0x33,
0x37, 0xea, 0x61, 0xa0, 0xae, 0x3e, 0xca, 0xd1, 0x9f, 0x05, 0xea, 0x4a, 0x8e, 0x1c, 0xe5, 0x92, 0x66, 0xa5, 0xd7, 0x2d, 0x2f, 0x3f, 0xcc, 0xd0, 0x9f, 0x76, 0xcb, 0x4b, 0x19, 0x72, 0x94, 0x09,
0xc1, 0x7b, 0x60, 0x49, 0x5e, 0xce, 0x36, 0x76, 0xb1, 0x61, 0xb1, 0x41, 0xb5, 0x28, 0x22, 0x5c, 0x06, 0xef, 0x81, 0x79, 0x75, 0x39, 0x9b, 0xd8, 0xc7, 0x96, 0xc3, 0x3b, 0xc5, 0xbc, 0xcc, 0x70,
0x09, 0x03, 0x75, 0xa9, 0x9d, 0x56, 0xa1, 0xac, 0x2d, 0x7c, 0x00, 0x16, 0x8f, 0xfd, 0xf7, 0x3d, 0xa9, 0xd7, 0x2d, 0xcf, 0xd7, 0x92, 0x2a, 0x94, 0xb6, 0x85, 0x0f, 0xc0, 0xdc, 0x31, 0xfb, 0x30,
0xda, 0x73, 0x0f, 0x69, 0xd7, 0x32, 0x06, 0xd5, 0xd2, 0xba, 0xb2, 0x31, 0xdf, 0xd0, 0xc2, 0x40, 0xa0, 0x2d, 0xff, 0x80, 0x36, 0x1d, 0xab, 0x53, 0x9c, 0x58, 0xd5, 0xd6, 0x66, 0x4c, 0xbd, 0xd7,
0x5d, 0xbc, 0xdf, 0x4e, 0x28, 0xce, 0xb2, 0x02, 0x94, 0x06, 0x6a, 0x3f, 0x2a, 0x60, 0x76, 0xbb, 0x2d, 0xcf, 0xdd, 0xaf, 0xc5, 0x14, 0xa7, 0x69, 0x01, 0x4a, 0x3a, 0xc2, 0x47, 0x60, 0x8e, 0xd3,
0xbd, 0xbb, 0x4f, 0x4d, 0x72, 0x09, 0x4d, 0xbe, 0x93, 0x6a, 0x72, 0x6d, 0x72, 0xaf, 0xf0, 0x78, 0x06, 0xf1, 0xc4, 0xd5, 0x11, 0xc6, 0x59, 0x71, 0x52, 0x96, 0xf1, 0xca, 0x88, 0x32, 0x1e, 0xc6,
0x26, 0xb6, 0xf8, 0xdf, 0x51, 0x8b, 0x73, 0x1b, 0x39, 0x9e, 0xeb, 0xa0, 0xe8, 0x60, 0x9b, 0x88, 0x6c, 0xcd, 0xcb, 0xaa, 0x92, 0x73, 0x71, 0x29, 0x43, 0x49, 0x40, 0xb8, 0x09, 0x16, 0x83, 0xb0,
0xa8, 0xe7, 0x63, 0xcc, 0x3e, 0xb6, 0x09, 0x12, 0x1a, 0xf8, 0x3a, 0x98, 0x71, 0xa8, 0x49, 0x76, 0x2e, 0x0c, 0x11, 0xbf, 0x75, 0xd4, 0x74, 0xd8, 0x49, 0x71, 0x4a, 0x1e, 0xf6, 0x72, 0xaf, 0x5b,
0x77, 0x84, 0xef, 0xf9, 0xc6, 0x15, 0x69, 0x33, 0xb3, 0x2f, 0xa4, 0x48, 0x6a, 0xe1, 0x2d, 0xb0, 0x5e, 0x44, 0x69, 0x25, 0x1a, 0xb6, 0xd7, 0x7f, 0xd6, 0xc0, 0xd4, 0x66, 0x6d, 0x7b, 0x8f, 0xda,
0xc0, 0xa8, 0x4b, 0xbb, 0xb4, 0x33, 0xf8, 0x80, 0x0c, 0x86, 0x55, 0xaf, 0x84, 0x81, 0xba, 0xf0, 0xe4, 0x02, 0x66, 0x71, 0x2b, 0x31, 0x8b, 0xfa, 0xe8, 0x96, 0x16, 0xf9, 0x8c, 0x9c, 0xc4, 0x7f,
0x30, 0x21, 0x47, 0x29, 0x2b, 0xf8, 0x29, 0x28, 0xe3, 0x6e, 0x97, 0x1a, 0x98, 0xe1, 0xa3, 0x2e, 0xc3, 0x49, 0x14, 0x36, 0x8a, 0x45, 0x56, 0x41, 0xde, 0xc3, 0x2e, 0x91, 0x59, 0xcf, 0x44, 0x3e,
0x11, 0xa5, 0x2c, 0xdf, 0xbc, 0x36, 0x21, 0xbd, 0xa8, 0x4b, 0xb8, 0x5f, 0x44, 0x7c, 0xda, 0xf3, 0x7b, 0xd8, 0x25, 0x48, 0x6a, 0xe0, 0x9b, 0x60, 0xd2, 0xa3, 0x36, 0xd9, 0xde, 0x92, 0xb1, 0x67,
0x0c, 0xe2, 0x37, 0x96, 0xc2, 0x40, 0x2d, 0x6f, 0xc5, 0x14, 0x28, 0xc9, 0xa7, 0xfd, 0xa0, 0x80, 0xcc, 0x4b, 0xca, 0x66, 0x72, 0x4f, 0x4a, 0x91, 0xd2, 0xc2, 0x5b, 0x60, 0x96, 0x53, 0x9f, 0x36,
0xb2, 0x4c, 0xf8, 0x12, 0x26, 0x7a, 0x3b, 0x3d, 0xd1, 0xb5, 0xf3, 0xab, 0x34, 0x61, 0x9e, 0x3f, 0x69, 0xbd, 0xf3, 0x11, 0xe9, 0xf4, 0x9b, 0x73, 0xa1, 0xd7, 0x2d, 0xcf, 0x1e, 0xc6, 0xe4, 0x28,
0x1b, 0x45, 0x2c, 0x86, 0xf9, 0x00, 0xcc, 0x9a, 0xa2, 0x54, 0x7e, 0x55, 0x11, 0xac, 0x57, 0xcf, 0x61, 0x05, 0x3f, 0x07, 0x05, 0xdc, 0x6c, 0x52, 0x0b, 0x73, 0x7c, 0xd4, 0x24, 0xb2, 0xe3, 0x0a,
0x67, 0x95, 0xbb, 0x62, 0x49, 0x72, 0xcf, 0x46, 0x67, 0x1f, 0x0d, 0x59, 0xb4, 0x6f, 0x66, 0xc0, 0x37, 0xaf, 0x8d, 0x38, 0x5e, 0xd8, 0xcc, 0x22, 0x2e, 0x22, 0x8c, 0xb6, 0x02, 0x8b, 0x30, 0x73,
0xc2, 0x70, 0x4c, 0xba, 0xd8, 0xf7, 0x2f, 0xa1, 0x79, 0xdf, 0x05, 0x65, 0xd7, 0xa3, 0x7d, 0xcb, 0xbe, 0xd7, 0x2d, 0x17, 0x36, 0x22, 0x08, 0x14, 0xc7, 0xd3, 0x7f, 0xd2, 0x40, 0x41, 0x1d, 0xf8,
0xb7, 0xa8, 0x43, 0x3c, 0xd9, 0x47, 0x2b, 0x12, 0x52, 0x3e, 0x8c, 0x55, 0x28, 0x69, 0x07, 0x3b, 0x02, 0x88, 0x67, 0x33, 0x49, 0x3c, 0xa5, 0xb3, 0xab, 0x34, 0x82, 0x76, 0xbe, 0x18, 0x64, 0x2c,
0x00, 0xb8, 0xd8, 0xc3, 0x36, 0x61, 0x3c, 0xfb, 0x82, 0xc8, 0xfe, 0x9d, 0x09, 0xd9, 0x27, 0x33, 0x39, 0x67, 0x1f, 0x4c, 0xd9, 0xb2, 0x54, 0xac, 0xa8, 0x49, 0xd4, 0xab, 0x67, 0xa3, 0x2a, 0x4a,
0xd2, 0x0f, 0x47, 0xa8, 0xa6, 0xc3, 0xbc, 0x41, 0x1c, 0x5d, 0xac, 0x40, 0x09, 0x6a, 0x78, 0x0a, 0x9b, 0x57, 0xd8, 0x53, 0xe1, 0x37, 0x43, 0x7d, 0x14, 0xfd, 0xdb, 0x49, 0x30, 0xdb, 0x9f, 0xe6,
0x16, 0x3d, 0x62, 0x74, 0xb1, 0x65, 0xcb, 0xa5, 0x50, 0x14, 0x11, 0x36, 0xf9, 0x52, 0x40, 0x49, 0x26, 0x66, 0xec, 0x02, 0x9a, 0xf7, 0x7d, 0x50, 0xf0, 0x03, 0xda, 0x76, 0x98, 0x43, 0x3d, 0x12,
0xc5, 0x59, 0xa0, 0xde, 0x18, 0x7f, 0xa0, 0xf5, 0x43, 0xe2, 0xf9, 0x96, 0xcf, 0x88, 0xc3, 0xa2, 0xa8, 0x3e, 0x5a, 0x52, 0x2e, 0x85, 0x83, 0x48, 0x85, 0xe2, 0x76, 0xb0, 0x0e, 0x80, 0x8f, 0x03,
0x0e, 0x4d, 0x61, 0x50, 0x9a, 0x9b, 0xcf, 0x89, 0xcd, 0xd7, 0xe5, 0x81, 0xcb, 0x2c, 0xea, 0xf8, 0xec, 0x12, 0x2e, 0x4e, 0x9f, 0x93, 0xa7, 0x7f, 0x6f, 0xc4, 0xe9, 0xe3, 0x27, 0x32, 0x0e, 0x06,
0xd5, 0x52, 0x3c, 0x27, 0xad, 0x84, 0x1c, 0xa5, 0xac, 0xe0, 0x1e, 0x58, 0xe5, 0x7d, 0xfd, 0x45, 0x5e, 0x55, 0x8f, 0x07, 0x9d, 0x28, 0xbb, 0x48, 0x81, 0x62, 0xd0, 0xb0, 0x01, 0xe6, 0x02, 0x62,
0xe4, 0xa0, 0xf9, 0xa5, 0x8b, 0x1d, 0x7e, 0x4b, 0xd5, 0x19, 0xb1, 0xfb, 0xaa, 0x7c, 0xb7, 0x6e, 0x35, 0xb1, 0xe3, 0x2a, 0xee, 0xca, 0xcb, 0x0c, 0xab, 0x82, 0x48, 0x50, 0x5c, 0x71, 0xda, 0x2d,
0xe5, 0xe8, 0x51, 0x2e, 0x0a, 0x7e, 0x04, 0x96, 0xa3, 0xe5, 0xda, 0xb0, 0x1c, 0xd3, 0x72, 0x3a, 0xdf, 0x18, 0x7e, 0x47, 0x18, 0x07, 0x24, 0x60, 0x0e, 0xe3, 0xc4, 0xe3, 0x61, 0x87, 0x26, 0x7c,
0x7c, 0xb5, 0x56, 0x67, 0x45, 0xd2, 0xd7, 0xc2, 0x40, 0x5d, 0x7e, 0x94, 0x55, 0x9e, 0xe5, 0x09, 0x50, 0x12, 0x5b, 0xcc, 0x89, 0x2b, 0x58, 0x7d, 0xdf, 0xe7, 0x0e, 0xf5, 0x58, 0x71, 0x22, 0x9a,
0xd1, 0x38, 0x09, 0x7c, 0x02, 0x96, 0x85, 0x47, 0x62, 0xca, 0xa1, 0xb7, 0x88, 0x5f, 0x9d, 0x13, 0x93, 0xdd, 0x98, 0x1c, 0x25, 0xac, 0xe0, 0x0e, 0x58, 0x16, 0x7d, 0xfd, 0x65, 0x18, 0xa0, 0xfa,
0xa5, 0xdb, 0x48, 0x96, 0x8e, 0x5f, 0x1d, 0xaf, 0xdb, 0x70, 0x35, 0xb4, 0x49, 0x97, 0x18, 0x8c, 0xd4, 0xc7, 0x9e, 0xb8, 0xa5, 0xe2, 0xa4, 0x64, 0xad, 0xa2, 0x58, 0x01, 0x1b, 0x19, 0x7a, 0x94,
0x7a, 0x0f, 0x89, 0x67, 0x37, 0xfe, 0x2f, 0xeb, 0xb5, 0xbc, 0x95, 0xa5, 0x42, 0xe3, 0xec, 0x6b, 0xe9, 0x05, 0x3f, 0x01, 0x8b, 0xe1, 0x0e, 0x30, 0x1d, 0xcf, 0x76, 0xbc, 0xba, 0xd8, 0x00, 0x92,
0xf7, 0xc0, 0x52, 0xa6, 0xe0, 0xb0, 0x02, 0x0a, 0xa7, 0x64, 0x10, 0x2d, 0x35, 0xc4, 0x7f, 0xc2, 0x00, 0x67, 0xcc, 0x6b, 0x82, 0x00, 0x1f, 0xa6, 0x95, 0xa7, 0x59, 0x42, 0x34, 0x0c, 0x02, 0x9f,
0x55, 0x50, 0xea, 0xe3, 0x6e, 0x8f, 0x44, 0xcd, 0x87, 0xa2, 0xc3, 0xdd, 0xe9, 0x3b, 0x8a, 0xf6, 0x80, 0x45, 0x19, 0x91, 0xd8, 0x6a, 0xe8, 0x1d, 0xc2, 0x8a, 0xd3, 0xb2, 0x74, 0x6b, 0xf1, 0xd2,
0x8b, 0x02, 0x2a, 0xc9, 0xee, 0xb9, 0x84, 0x3d, 0xf1, 0x20, 0xbd, 0x27, 0x5e, 0xbb, 0x40, 0x4f, 0x89, 0xab, 0x0b, 0xd9, 0x3b, 0x24, 0x83, 0x1a, 0x69, 0x12, 0x8b, 0xd3, 0xe0, 0x90, 0x04, 0xae,
0x4f, 0x58, 0x16, 0xdf, 0x4f, 0x83, 0x4a, 0x54, 0x97, 0xe8, 0x5d, 0xb7, 0x89, 0xc3, 0x2e, 0x61, 0xf9, 0x86, 0xaa, 0xd7, 0xe2, 0x46, 0x1a, 0x0a, 0x0d, 0xa3, 0xaf, 0xdc, 0x03, 0xf3, 0xa9, 0x82,
0xa0, 0x5b, 0xa9, 0xd7, 0xe8, 0xad, 0x73, 0xd7, 0x75, 0x1c, 0xd8, 0xa4, 0x67, 0x09, 0x7e, 0x08, 0xc3, 0x05, 0x90, 0x6b, 0x90, 0x4e, 0x48, 0x6a, 0x48, 0xfc, 0x84, 0xcb, 0x60, 0xa2, 0x8d, 0x9b,
0x66, 0x7c, 0x86, 0x59, 0x8f, 0x0f, 0x39, 0x27, 0xbc, 0x7e, 0x51, 0x42, 0x01, 0x8a, 0x5f, 0xa4, 0x2d, 0x12, 0x36, 0x1f, 0x0a, 0x3f, 0xee, 0x8e, 0xdf, 0xd1, 0xf4, 0xdf, 0x34, 0xb0, 0x10, 0xef,
0xe8, 0x8c, 0x24, 0x99, 0xf6, 0xab, 0x02, 0x56, 0xb3, 0x90, 0x4b, 0xa8, 0xee, 0x5e, 0xba, 0xba, 0x9e, 0x0b, 0xe0, 0x89, 0x07, 0x49, 0x9e, 0xb8, 0x72, 0x8e, 0x9e, 0x1e, 0x41, 0x16, 0x5f, 0x6b,
0x6f, 0x5c, 0x30, 0x99, 0x09, 0x15, 0xfe, 0x5d, 0x01, 0xff, 0x1d, 0xcb, 0x5b, 0xbc, 0x7d, 0x7c, 0x60, 0x36, 0xbe, 0xea, 0xe0, 0xbb, 0x60, 0x1a, 0xb7, 0x6c, 0x87, 0x78, 0x56, 0x9f, 0xd3, 0x07,
0x27, 0xb8, 0x99, 0xcd, 0xb3, 0x1f, 0xbf, 0xe5, 0x62, 0x27, 0x1c, 0xe6, 0xe8, 0x51, 0x2e, 0x0a, 0x89, 0x6c, 0x28, 0x39, 0x1a, 0x58, 0x88, 0x45, 0x48, 0x9e, 0xfa, 0x4e, 0x80, 0x45, 0x93, 0xd5,
0x3e, 0x06, 0x15, 0xcb, 0xe9, 0x5a, 0x0e, 0x89, 0x64, 0xed, 0xb8, 0xbe, 0xb9, 0x83, 0x9b, 0x65, 0x88, 0x45, 0x3d, 0x9b, 0xc9, 0x1b, 0xca, 0x85, 0x8b, 0xb0, 0x9a, 0x56, 0xa2, 0x61, 0x7b, 0xfd,
0x16, 0xc5, 0x5d, 0x0d, 0x03, 0xb5, 0xb2, 0x9b, 0x61, 0x41, 0x63, 0xbc, 0xda, 0x6f, 0x39, 0x95, 0x87, 0x71, 0xb0, 0x10, 0xf6, 0x46, 0xf8, 0x04, 0x72, 0x89, 0xc7, 0x2f, 0x80, 0x54, 0x76, 0x13,
0x11, 0xaf, 0xdd, 0xdb, 0x60, 0x2e, 0xfa, 0x20, 0x25, 0x9e, 0x4c, 0x63, 0x74, 0xd3, 0x5b, 0x52, 0x1b, 0xf1, 0x9d, 0x33, 0x57, 0x46, 0x94, 0xd8, 0xa8, 0xd5, 0x08, 0x3f, 0x06, 0x93, 0x8c, 0x63,
0x8e, 0x46, 0x16, 0xa2, 0x6f, 0xc4, 0x55, 0xc8, 0x40, 0x2f, 0xdc, 0x37, 0x02, 0x94, 0xe8, 0x1b, 0xde, 0x12, 0x44, 0x23, 0x00, 0xaf, 0x9f, 0x17, 0x50, 0x3a, 0x45, 0x5b, 0x31, 0xfc, 0x46, 0x0a,
0x71, 0x46, 0x92, 0x8c, 0x07, 0xc1, 0xbf, 0x69, 0xc4, 0x5d, 0x16, 0xd2, 0x41, 0xec, 0x4b, 0x39, 0x4c, 0xff, 0x5d, 0x03, 0xcb, 0x69, 0x97, 0x0b, 0xe8, 0xb0, 0x9d, 0x64, 0x87, 0xbd, 0x75, 0xce,
0x1a, 0x59, 0x68, 0x7f, 0x15, 0x72, 0x0a, 0x24, 0x1a, 0x30, 0x91, 0xcd, 0xf0, 0x13, 0x3c, 0x9b, 0xc3, 0x8c, 0xe8, 0xb2, 0x3f, 0x35, 0xf0, 0xbf, 0xa1, 0x73, 0xcb, 0xfd, 0x2b, 0x78, 0xc9, 0x4f,
0x8d, 0x39, 0xca, 0xc6, 0x84, 0xdf, 0x29, 0x00, 0xe2, 0x11, 0x45, 0x6b, 0xd8, 0xa0, 0x51, 0x17, 0xb1, 0xdf, 0x5e, 0xf4, 0x9e, 0x90, 0xbc, 0x74, 0x90, 0xa1, 0x47, 0x99, 0x5e, 0xf0, 0x31, 0x58,
0x35, 0x5f, 0x69, 0x24, 0xf4, 0xad, 0x31, 0x9e, 0xe8, 0x25, 0x5c, 0x93, 0xfe, 0xe1, 0xb8, 0x01, 0x70, 0xbc, 0xa6, 0xe3, 0x91, 0x50, 0x56, 0x8b, 0xea, 0x9b, 0x49, 0x1e, 0x69, 0x64, 0x59, 0xdc,
0xca, 0x71, 0x0e, 0x4d, 0x50, 0x8e, 0xa4, 0x4d, 0xcf, 0xa3, 0x9e, 0x1c, 0x4f, 0xed, 0xdc, 0x58, 0xe5, 0x5e, 0xb7, 0xbc, 0xb0, 0x9d, 0x42, 0x41, 0x43, 0xb8, 0xfa, 0x1f, 0x19, 0x95, 0x91, 0x1b,
0x84, 0x65, 0xa3, 0x26, 0x3e, 0xcb, 0x62, 0xe8, 0x59, 0xa0, 0x96, 0x13, 0x7a, 0x94, 0xa4, 0xe5, 0x57, 0x8c, 0x90, 0x94, 0x90, 0x60, 0x68, 0x84, 0x94, 0x1c, 0x0d, 0x2c, 0x64, 0xdf, 0xc8, 0xab,
0x5e, 0x4c, 0x12, 0x7b, 0x29, 0xbe, 0x9a, 0x97, 0x1d, 0x32, 0xd9, 0x4b, 0x82, 0x76, 0xad, 0x09, 0x50, 0x89, 0x9e, 0xbb, 0x6f, 0xa4, 0x53, 0xac, 0x6f, 0xe4, 0x37, 0x52, 0x60, 0x22, 0x09, 0xf1,
0xfe, 0x37, 0xe1, 0x5a, 0x5e, 0xe9, 0xbd, 0xf8, 0x5a, 0x01, 0x49, 0x1f, 0x70, 0x0f, 0x14, 0xf9, 0xae, 0x92, 0x77, 0x99, 0x4b, 0x26, 0xb1, 0xa7, 0xe4, 0x68, 0x60, 0xa1, 0xff, 0x93, 0xcb, 0x28,
0xbf, 0x61, 0xb9, 0x48, 0xae, 0x5d, 0x6c, 0x91, 0x3c, 0xb4, 0x6c, 0x12, 0xaf, 0x42, 0x7e, 0x42, 0x90, 0x6c, 0xc0, 0xd8, 0x69, 0xfa, 0xff, 0x56, 0xd2, 0xa7, 0xb1, 0x07, 0xa7, 0xb1, 0xe1, 0xf7,
0x82, 0x05, 0xbe, 0x09, 0x66, 0x6d, 0xe2, 0xfb, 0xb8, 0x23, 0x3d, 0xc7, 0x1f, 0x72, 0xad, 0x48, 0x1a, 0x80, 0x78, 0x00, 0xb1, 0xdb, 0x6f, 0xd0, 0xb0, 0x8b, 0xaa, 0xaf, 0x35, 0x12, 0xc6, 0xc6,
0x8c, 0x86, 0x7a, 0xed, 0x36, 0x58, 0xc9, 0xf9, 0x20, 0x86, 0x2a, 0x28, 0x19, 0xe2, 0x8f, 0x1b, 0x10, 0x4e, 0xb8, 0x8d, 0x57, 0x54, 0x7c, 0x38, 0x6c, 0x80, 0x32, 0x82, 0x43, 0x1b, 0x14, 0x42,
0x0f, 0xa8, 0xd4, 0x98, 0xe7, 0x1b, 0x65, 0x5b, 0xfc, 0x5f, 0x8b, 0xe4, 0x8d, 0x8d, 0xa7, 0x2f, 0x69, 0x35, 0x08, 0x68, 0xa0, 0xc6, 0x53, 0x3f, 0x33, 0x17, 0x69, 0x69, 0x96, 0xe4, 0xd3, 0x30,
0x6a, 0x53, 0xcf, 0x5e, 0xd4, 0xa6, 0x9e, 0xbf, 0xa8, 0x4d, 0x7d, 0x15, 0xd6, 0x94, 0xa7, 0x61, 0x72, 0x3d, 0xed, 0x96, 0x0b, 0x31, 0x3d, 0x8a, 0xc3, 0x8a, 0x28, 0x36, 0x89, 0xa2, 0xe4, 0x5f,
0x4d, 0x79, 0x16, 0xd6, 0x94, 0xe7, 0x61, 0x4d, 0xf9, 0x23, 0xac, 0x29, 0xdf, 0xfe, 0x59, 0x9b, 0x2f, 0xca, 0x16, 0x19, 0x1d, 0x25, 0x06, 0xbb, 0x52, 0x05, 0xff, 0x1f, 0x71, 0x2d, 0xaf, 0xb5,
0xfa, 0x78, 0xba, 0xbf, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9e, 0x83, 0x24, 0x44, 0x13, 0xb3, 0xbe, 0xd1, 0x40, 0x3c, 0x06, 0xdc, 0x01, 0x79, 0xee, 0xa8, 0xa9, 0x4b, 0x3e, 0x9f, 0xcf,
0x11, 0x00, 0x00, 0x20, 0x92, 0x43, 0xc7, 0x25, 0x11, 0x15, 0x8a, 0x2f, 0x24, 0x51, 0xe0, 0xdb, 0x60, 0xca, 0x25,
0x8c, 0xe1, 0xba, 0x8a, 0x1c, 0x3d, 0x26, 0x77, 0x43, 0x31, 0xea, 0xeb, 0xf5, 0xdb, 0x60, 0x29,
0xe3, 0x51, 0x0e, 0xcb, 0x60, 0xc2, 0x92, 0xff, 0x71, 0x45, 0x42, 0x13, 0xe6, 0x8c, 0x60, 0x94,
0x4d, 0xf9, 0xd7, 0x36, 0x94, 0x9b, 0x6b, 0xcf, 0x5e, 0x96, 0xc6, 0x9e, 0xbf, 0x2c, 0x8d, 0xbd,
0x78, 0x59, 0x1a, 0xfb, 0xaa, 0x57, 0xd2, 0x9e, 0xf5, 0x4a, 0xda, 0xf3, 0x5e, 0x49, 0x7b, 0xd1,
0x2b, 0x69, 0x7f, 0xf5, 0x4a, 0xda, 0x77, 0x7f, 0x97, 0xc6, 0x3e, 0x1d, 0x6f, 0xaf, 0xff, 0x17,
0x00, 0x00, 0xff, 0xff, 0x02, 0xb2, 0x6f, 0xe2, 0x3e, 0x12, 0x00, 0x00,
} }
func (m *CSIDriver) Marshal() (dAtA []byte, err error) { func (m *CSIDriver) Marshal() (dAtA []byte, err error) {
@ -721,6 +756,30 @@ func (m *CSIDriverSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.RequiresRepublish != nil {
i--
if *m.RequiresRepublish {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x38
}
if len(m.TokenRequests) > 0 {
for iNdEx := len(m.TokenRequests) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.TokenRequests[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x32
}
}
if m.FSGroupPolicy != nil { if m.FSGroupPolicy != nil {
i -= len(*m.FSGroupPolicy) i -= len(*m.FSGroupPolicy)
copy(dAtA[i:], *m.FSGroupPolicy) copy(dAtA[i:], *m.FSGroupPolicy)
@ -1107,6 +1166,39 @@ func (m *StorageClassList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *TokenRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TokenRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.ExpirationSeconds != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.ExpirationSeconds))
i--
dAtA[i] = 0x10
}
i -= len(m.Audience)
copy(dAtA[i:], m.Audience)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Audience)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func (m *VolumeAttachment) Marshal() (dAtA []byte, err error) { func (m *VolumeAttachment) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
@ -1503,6 +1595,15 @@ func (m *CSIDriverSpec) Size() (n int) {
l = len(*m.FSGroupPolicy) l = len(*m.FSGroupPolicy)
n += 1 + l + sovGenerated(uint64(l)) n += 1 + l + sovGenerated(uint64(l))
} }
if len(m.TokenRequests) > 0 {
for _, e := range m.TokenRequests {
l = e.Size()
n += 1 + l + sovGenerated(uint64(l))
}
}
if m.RequiresRepublish != nil {
n += 2
}
return n return n
} }
@ -1635,6 +1736,20 @@ func (m *StorageClassList) Size() (n int) {
return n return n
} }
func (m *TokenRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Audience)
n += 1 + l + sovGenerated(uint64(l))
if m.ExpirationSeconds != nil {
n += 1 + sovGenerated(uint64(*m.ExpirationSeconds))
}
return n
}
func (m *VolumeAttachment) Size() (n int) { func (m *VolumeAttachment) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
@ -1787,12 +1902,19 @@ func (this *CSIDriverSpec) String() string {
if this == nil { if this == nil {
return "nil" return "nil"
} }
repeatedStringForTokenRequests := "[]TokenRequest{"
for _, f := range this.TokenRequests {
repeatedStringForTokenRequests += strings.Replace(strings.Replace(f.String(), "TokenRequest", "TokenRequest", 1), `&`, ``, 1) + ","
}
repeatedStringForTokenRequests += "}"
s := strings.Join([]string{`&CSIDriverSpec{`, s := strings.Join([]string{`&CSIDriverSpec{`,
`AttachRequired:` + valueToStringGenerated(this.AttachRequired) + `,`, `AttachRequired:` + valueToStringGenerated(this.AttachRequired) + `,`,
`PodInfoOnMount:` + valueToStringGenerated(this.PodInfoOnMount) + `,`, `PodInfoOnMount:` + valueToStringGenerated(this.PodInfoOnMount) + `,`,
`VolumeLifecycleModes:` + fmt.Sprintf("%v", this.VolumeLifecycleModes) + `,`, `VolumeLifecycleModes:` + fmt.Sprintf("%v", this.VolumeLifecycleModes) + `,`,
`StorageCapacity:` + valueToStringGenerated(this.StorageCapacity) + `,`, `StorageCapacity:` + valueToStringGenerated(this.StorageCapacity) + `,`,
`FSGroupPolicy:` + valueToStringGenerated(this.FSGroupPolicy) + `,`, `FSGroupPolicy:` + valueToStringGenerated(this.FSGroupPolicy) + `,`,
`TokenRequests:` + repeatedStringForTokenRequests + `,`,
`RequiresRepublish:` + valueToStringGenerated(this.RequiresRepublish) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@ -1900,6 +2022,17 @@ func (this *StorageClassList) String() string {
}, "") }, "")
return s return s
} }
func (this *TokenRequest) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&TokenRequest{`,
`Audience:` + fmt.Sprintf("%v", this.Audience) + `,`,
`ExpirationSeconds:` + valueToStringGenerated(this.ExpirationSeconds) + `,`,
`}`,
}, "")
return s
}
func (this *VolumeAttachment) String() string { func (this *VolumeAttachment) String() string {
if this == nil { if this == nil {
return "nil" return "nil"
@ -2399,6 +2532,61 @@ func (m *CSIDriverSpec) Unmarshal(dAtA []byte) error {
s := FSGroupPolicy(dAtA[iNdEx:postIndex]) s := FSGroupPolicy(dAtA[iNdEx:postIndex])
m.FSGroupPolicy = &s m.FSGroupPolicy = &s
iNdEx = postIndex iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TokenRequests", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.TokenRequests = append(m.TokenRequests, TokenRequest{})
if err := m.TokenRequests[len(m.TokenRequests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RequiresRepublish", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
b := bool(v != 0)
m.RequiresRepublish = &b
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:]) skippy, err := skipGenerated(dAtA[iNdEx:])
@ -3452,6 +3640,111 @@ func (m *StorageClassList) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *TokenRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TokenRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TokenRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Audience", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Audience = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ExpirationSeconds", wireType)
}
var v int64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.ExpirationSeconds = &v
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *VolumeAttachment) Unmarshal(dAtA []byte) error { func (m *VolumeAttachment) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0

View File

@ -146,6 +146,43 @@ message CSIDriverSpec {
// that enable the CSIVolumeFSGroupPolicy feature gate. // that enable the CSIVolumeFSGroupPolicy feature gate.
// +optional // +optional
optional string fsGroupPolicy = 5; optional string fsGroupPolicy = 5;
// TokenRequests indicates the CSI driver needs pods' service account
// tokens it is mounting volume for to do necessary authentication. Kubelet
// will pass the tokens in VolumeContext in the CSI NodePublishVolume calls.
// The CSI driver should parse and validate the following VolumeContext:
// "csi.storage.k8s.io/serviceAccount.tokens": {
// "<audience>": {
// "token": <token>,
// "expirationTimestamp": <expiration timestamp in RFC3339>,
// },
// ...
// }
//
// Note: Audience in each TokenRequest should be different and at
// most one token is empty string. To receive a new token after expiry,
// RequiresRepublish can be used to trigger NodePublishVolume periodically.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
// +listType=atomic
repeated TokenRequest tokenRequests = 6;
// RequiresRepublish indicates the CSI driver wants `NodePublishVolume`
// being periodically called to reflect any possible change in the mounted
// volume. This field defaults to false.
//
// Note: After a successful initial NodePublishVolume call, subsequent calls
// to NodePublishVolume should only update the contents of the volume. New
// mount points will not be seen by a running container.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
optional bool requiresRepublish = 7;
} }
// CSINode holds information about all CSI drivers installed on a node. // CSINode holds information about all CSI drivers installed on a node.
@ -281,6 +318,19 @@ message StorageClassList {
repeated StorageClass items = 2; repeated StorageClass items = 2;
} }
// TokenRequest contains parameters of a service account token.
message TokenRequest {
// Audience is the intended audience of the token in "TokenRequestSpec".
// It will default to the audiences of kube apiserver.
optional string audience = 1;
// ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec".
// It has the same default value of "ExpirationSeconds" in "TokenRequestSpec".
//
// +optional
optional int64 expirationSeconds = 2;
}
// VolumeAttachment captures the intent to attach or detach the specified volume // VolumeAttachment captures the intent to attach or detach the specified volume
// to/from the specified node. // to/from the specified node.
// //

View File

@ -344,6 +344,43 @@ type CSIDriverSpec struct {
// that enable the CSIVolumeFSGroupPolicy feature gate. // that enable the CSIVolumeFSGroupPolicy feature gate.
// +optional // +optional
FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"` FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"`
// TokenRequests indicates the CSI driver needs pods' service account
// tokens it is mounting volume for to do necessary authentication. Kubelet
// will pass the tokens in VolumeContext in the CSI NodePublishVolume calls.
// The CSI driver should parse and validate the following VolumeContext:
// "csi.storage.k8s.io/serviceAccount.tokens": {
// "<audience>": {
// "token": <token>,
// "expirationTimestamp": <expiration timestamp in RFC3339>,
// },
// ...
// }
//
// Note: Audience in each TokenRequest should be different and at
// most one token is empty string. To receive a new token after expiry,
// RequiresRepublish can be used to trigger NodePublishVolume periodically.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
// +listType=atomic
TokenRequests []TokenRequest `json:"tokenRequests,omitempty" protobuf:"bytes,6,opt,name=tokenRequests"`
// RequiresRepublish indicates the CSI driver wants `NodePublishVolume`
// being periodically called to reflect any possible change in the mounted
// volume. This field defaults to false.
//
// Note: After a successful initial NodePublishVolume call, subsequent calls
// to NodePublishVolume should only update the contents of the volume. New
// mount points will not be seen by a running container.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"`
} }
// FSGroupPolicy specifies if a CSI Driver supports modifying // FSGroupPolicy specifies if a CSI Driver supports modifying
@ -381,6 +418,20 @@ const (
// provided by a CSI driver. More modes may be added in the future. // provided by a CSI driver. More modes may be added in the future.
type VolumeLifecycleMode string type VolumeLifecycleMode string
// TokenRequest contains parameters of a service account token.
type TokenRequest struct {
// Audience is the intended audience of the token in "TokenRequestSpec".
// It will default to the audiences of kube apiserver.
//
Audience string `json:"audience" protobuf:"bytes,1,opt,name=audience"`
// ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec".
// It has the same default value of "ExpirationSeconds" in "TokenRequestSpec".
//
// +optional
ExpirationSeconds *int64 `json:"expirationSeconds,omitempty" protobuf:"varint,2,opt,name=expirationSeconds"`
}
const ( const (
// VolumeLifecyclePersistent explicitly confirms that the driver implements // VolumeLifecyclePersistent explicitly confirms that the driver implements
// the full CSI spec. It is the default when CSIDriverSpec.VolumeLifecycleModes is not // the full CSI spec. It is the default when CSIDriverSpec.VolumeLifecycleModes is not

View File

@ -54,6 +54,8 @@ var map_CSIDriverSpec = map[string]string{
"volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.", "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.",
"storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.", "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.",
"fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details. This field is alpha-level, and is only honored by servers that enable the CSIVolumeFSGroupPolicy feature gate.", "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details. This field is alpha-level, and is only honored by servers that enable the CSIVolumeFSGroupPolicy feature gate.",
"tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"<audience>\": {\n \"token\": <token>,\n \"expirationTimestamp\": <expiration timestamp in RFC3339>,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
"requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
} }
func (CSIDriverSpec) SwaggerDoc() map[string]string { func (CSIDriverSpec) SwaggerDoc() map[string]string {
@ -127,6 +129,16 @@ func (StorageClassList) SwaggerDoc() map[string]string {
return map_StorageClassList return map_StorageClassList
} }
var map_TokenRequest = map[string]string{
"": "TokenRequest contains parameters of a service account token.",
"audience": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.",
"expirationSeconds": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\".",
}
func (TokenRequest) SwaggerDoc() map[string]string {
return map_TokenRequest
}
var map_VolumeAttachment = map[string]string{ var map_VolumeAttachment = map[string]string{
"": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.",
"metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",

View File

@ -113,6 +113,18 @@ func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) {
*out = new(FSGroupPolicy) *out = new(FSGroupPolicy)
**out = **in **out = **in
} }
if in.TokenRequests != nil {
in, out := &in.TokenRequests, &out.TokenRequests
*out = make([]TokenRequest, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.RequiresRepublish != nil {
in, out := &in.RequiresRepublish, &out.RequiresRepublish
*out = new(bool)
**out = **in
}
return return
} }
@ -328,6 +340,27 @@ func (in *StorageClassList) DeepCopyObject() runtime.Object {
return nil return nil
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenRequest) DeepCopyInto(out *TokenRequest) {
*out = *in
if in.ExpirationSeconds != nil {
in, out := &in.ExpirationSeconds, &out.ExpirationSeconds
*out = new(int64)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenRequest.
func (in *TokenRequest) DeepCopy() *TokenRequest {
if in == nil {
return nil
}
out := new(TokenRequest)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeAttachment) DeepCopyInto(out *VolumeAttachment) { func (in *VolumeAttachment) DeepCopyInto(out *VolumeAttachment) {
*out = *in *out = *in

View File

@ -298,10 +298,38 @@ func (m *StorageClassList) XXX_DiscardUnknown() {
var xxx_messageInfo_StorageClassList proto.InternalMessageInfo var xxx_messageInfo_StorageClassList proto.InternalMessageInfo
func (m *TokenRequest) Reset() { *m = TokenRequest{} }
func (*TokenRequest) ProtoMessage() {}
func (*TokenRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{9}
}
func (m *TokenRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TokenRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
func (m *TokenRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_TokenRequest.Merge(m, src)
}
func (m *TokenRequest) XXX_Size() int {
return m.Size()
}
func (m *TokenRequest) XXX_DiscardUnknown() {
xxx_messageInfo_TokenRequest.DiscardUnknown(m)
}
var xxx_messageInfo_TokenRequest proto.InternalMessageInfo
func (m *VolumeAttachment) Reset() { *m = VolumeAttachment{} } func (m *VolumeAttachment) Reset() { *m = VolumeAttachment{} }
func (*VolumeAttachment) ProtoMessage() {} func (*VolumeAttachment) ProtoMessage() {}
func (*VolumeAttachment) Descriptor() ([]byte, []int) { func (*VolumeAttachment) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{9} return fileDescriptor_7d2980599fd0de80, []int{10}
} }
func (m *VolumeAttachment) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachment) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -329,7 +357,7 @@ var xxx_messageInfo_VolumeAttachment proto.InternalMessageInfo
func (m *VolumeAttachmentList) Reset() { *m = VolumeAttachmentList{} } func (m *VolumeAttachmentList) Reset() { *m = VolumeAttachmentList{} }
func (*VolumeAttachmentList) ProtoMessage() {} func (*VolumeAttachmentList) ProtoMessage() {}
func (*VolumeAttachmentList) Descriptor() ([]byte, []int) { func (*VolumeAttachmentList) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{10} return fileDescriptor_7d2980599fd0de80, []int{11}
} }
func (m *VolumeAttachmentList) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentList) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -357,7 +385,7 @@ var xxx_messageInfo_VolumeAttachmentList proto.InternalMessageInfo
func (m *VolumeAttachmentSource) Reset() { *m = VolumeAttachmentSource{} } func (m *VolumeAttachmentSource) Reset() { *m = VolumeAttachmentSource{} }
func (*VolumeAttachmentSource) ProtoMessage() {} func (*VolumeAttachmentSource) ProtoMessage() {}
func (*VolumeAttachmentSource) Descriptor() ([]byte, []int) { func (*VolumeAttachmentSource) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{11} return fileDescriptor_7d2980599fd0de80, []int{12}
} }
func (m *VolumeAttachmentSource) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentSource) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -385,7 +413,7 @@ var xxx_messageInfo_VolumeAttachmentSource proto.InternalMessageInfo
func (m *VolumeAttachmentSpec) Reset() { *m = VolumeAttachmentSpec{} } func (m *VolumeAttachmentSpec) Reset() { *m = VolumeAttachmentSpec{} }
func (*VolumeAttachmentSpec) ProtoMessage() {} func (*VolumeAttachmentSpec) ProtoMessage() {}
func (*VolumeAttachmentSpec) Descriptor() ([]byte, []int) { func (*VolumeAttachmentSpec) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{12} return fileDescriptor_7d2980599fd0de80, []int{13}
} }
func (m *VolumeAttachmentSpec) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentSpec) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -413,7 +441,7 @@ var xxx_messageInfo_VolumeAttachmentSpec proto.InternalMessageInfo
func (m *VolumeAttachmentStatus) Reset() { *m = VolumeAttachmentStatus{} } func (m *VolumeAttachmentStatus) Reset() { *m = VolumeAttachmentStatus{} }
func (*VolumeAttachmentStatus) ProtoMessage() {} func (*VolumeAttachmentStatus) ProtoMessage() {}
func (*VolumeAttachmentStatus) Descriptor() ([]byte, []int) { func (*VolumeAttachmentStatus) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{13} return fileDescriptor_7d2980599fd0de80, []int{14}
} }
func (m *VolumeAttachmentStatus) XXX_Unmarshal(b []byte) error { func (m *VolumeAttachmentStatus) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -441,7 +469,7 @@ var xxx_messageInfo_VolumeAttachmentStatus proto.InternalMessageInfo
func (m *VolumeError) Reset() { *m = VolumeError{} } func (m *VolumeError) Reset() { *m = VolumeError{} }
func (*VolumeError) ProtoMessage() {} func (*VolumeError) ProtoMessage() {}
func (*VolumeError) Descriptor() ([]byte, []int) { func (*VolumeError) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{14} return fileDescriptor_7d2980599fd0de80, []int{15}
} }
func (m *VolumeError) XXX_Unmarshal(b []byte) error { func (m *VolumeError) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -469,7 +497,7 @@ var xxx_messageInfo_VolumeError proto.InternalMessageInfo
func (m *VolumeNodeResources) Reset() { *m = VolumeNodeResources{} } func (m *VolumeNodeResources) Reset() { *m = VolumeNodeResources{} }
func (*VolumeNodeResources) ProtoMessage() {} func (*VolumeNodeResources) ProtoMessage() {}
func (*VolumeNodeResources) Descriptor() ([]byte, []int) { func (*VolumeNodeResources) Descriptor() ([]byte, []int) {
return fileDescriptor_7d2980599fd0de80, []int{15} return fileDescriptor_7d2980599fd0de80, []int{16}
} }
func (m *VolumeNodeResources) XXX_Unmarshal(b []byte) error { func (m *VolumeNodeResources) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -505,6 +533,7 @@ func init() {
proto.RegisterType((*StorageClass)(nil), "k8s.io.api.storage.v1beta1.StorageClass") proto.RegisterType((*StorageClass)(nil), "k8s.io.api.storage.v1beta1.StorageClass")
proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.storage.v1beta1.StorageClass.ParametersEntry") proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.storage.v1beta1.StorageClass.ParametersEntry")
proto.RegisterType((*StorageClassList)(nil), "k8s.io.api.storage.v1beta1.StorageClassList") proto.RegisterType((*StorageClassList)(nil), "k8s.io.api.storage.v1beta1.StorageClassList")
proto.RegisterType((*TokenRequest)(nil), "k8s.io.api.storage.v1beta1.TokenRequest")
proto.RegisterType((*VolumeAttachment)(nil), "k8s.io.api.storage.v1beta1.VolumeAttachment") proto.RegisterType((*VolumeAttachment)(nil), "k8s.io.api.storage.v1beta1.VolumeAttachment")
proto.RegisterType((*VolumeAttachmentList)(nil), "k8s.io.api.storage.v1beta1.VolumeAttachmentList") proto.RegisterType((*VolumeAttachmentList)(nil), "k8s.io.api.storage.v1beta1.VolumeAttachmentList")
proto.RegisterType((*VolumeAttachmentSource)(nil), "k8s.io.api.storage.v1beta1.VolumeAttachmentSource") proto.RegisterType((*VolumeAttachmentSource)(nil), "k8s.io.api.storage.v1beta1.VolumeAttachmentSource")
@ -520,95 +549,102 @@ func init() {
} }
var fileDescriptor_7d2980599fd0de80 = []byte{ var fileDescriptor_7d2980599fd0de80 = []byte{
// 1400 bytes of a gzipped FileDescriptorProto // 1508 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x3d, 0x6f, 0xdb, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xbd, 0x6f, 0x1b, 0x47,
0x1f, 0x37, 0x2d, 0xc9, 0x2f, 0x27, 0x3b, 0x96, 0xcf, 0xc6, 0xf3, 0xe8, 0xd1, 0x20, 0x1a, 0x7a, 0x16, 0xd7, 0x8a, 0xd4, 0xd7, 0x50, 0xb2, 0xa4, 0x91, 0x7c, 0xc7, 0x53, 0x41, 0x0a, 0x3c, 0xdc,
0xd0, 0xc6, 0x09, 0x12, 0x2a, 0x31, 0xd2, 0x20, 0x08, 0x90, 0xc1, 0x72, 0xdc, 0x46, 0x89, 0xe5, 0x59, 0x36, 0xec, 0xa5, 0x2d, 0xf8, 0x0c, 0xc3, 0x80, 0x0b, 0xad, 0xac, 0x3b, 0xcb, 0x96, 0x64,
0xb8, 0x27, 0x23, 0x28, 0x82, 0x0e, 0x3d, 0x91, 0x67, 0x99, 0xb1, 0xc8, 0x63, 0xc8, 0x93, 0x5a, 0xdd, 0x50, 0x30, 0x0e, 0xc6, 0x15, 0x19, 0xee, 0x3e, 0x51, 0x6b, 0x71, 0x77, 0xd6, 0x3b, 0x43,
0x6d, 0x9d, 0x3a, 0x17, 0x1d, 0xfa, 0x09, 0xfa, 0x15, 0x5a, 0xa0, 0x5d, 0x3a, 0x36, 0x53, 0x11, 0xc5, 0xec, 0x92, 0x26, 0x75, 0x90, 0x22, 0x7d, 0x80, 0xfc, 0x0b, 0x09, 0x90, 0x34, 0x29, 0xe3,
0x74, 0xca, 0x44, 0x34, 0xec, 0x47, 0x28, 0xba, 0x18, 0x1d, 0x8a, 0x3b, 0x9e, 0xc4, 0x17, 0x51, 0x2a, 0x30, 0x52, 0xb9, 0x22, 0x62, 0xe6, 0x4f, 0x48, 0x27, 0xa4, 0x08, 0x66, 0x76, 0xc8, 0xfd,
0xb1, 0xdd, 0xc1, 0x1b, 0xef, 0xff, 0xf2, 0xfb, 0xbf, 0xff, 0xef, 0x08, 0x76, 0x4e, 0xee, 0x79, 0x20, 0x69, 0x49, 0x29, 0xd4, 0x71, 0xde, 0xc7, 0xef, 0xbd, 0x79, 0xef, 0xcd, 0xef, 0x2d, 0xd1,
0x9a, 0x49, 0xeb, 0x27, 0xfd, 0x0e, 0x71, 0x6d, 0xc2, 0x88, 0x57, 0x1f, 0x10, 0xdb, 0xa0, 0x6e, 0xe6, 0xf1, 0x7d, 0x6e, 0xba, 0xac, 0x7a, 0xdc, 0xaa, 0x43, 0xe8, 0x83, 0x00, 0x5e, 0x3d, 0x01,
0x5d, 0x32, 0xb0, 0x63, 0xd6, 0x3d, 0x46, 0x5d, 0xdc, 0x25, 0xf5, 0xc1, 0xed, 0x0e, 0x61, 0xf8, 0xdf, 0x61, 0x61, 0x55, 0x2b, 0x68, 0xe0, 0x56, 0xb9, 0x60, 0x21, 0x6d, 0x40, 0xf5, 0xe4, 0x4e,
0x76, 0xbd, 0x4b, 0x6c, 0xe2, 0x62, 0x46, 0x0c, 0xcd, 0x71, 0x29, 0xa3, 0xb0, 0x12, 0xca, 0x6a, 0x1d, 0x04, 0xbd, 0x53, 0x6d, 0x80, 0x0f, 0x21, 0x15, 0xe0, 0x98, 0x41, 0xc8, 0x04, 0xc3, 0x2b,
0xd8, 0x31, 0x35, 0x29, 0xab, 0x49, 0xd9, 0xca, 0xcd, 0xae, 0xc9, 0x8e, 0xfb, 0x1d, 0x4d, 0xa7, 0x91, 0xad, 0x49, 0x03, 0xd7, 0xd4, 0xb6, 0xa6, 0xb6, 0x5d, 0xb9, 0xd5, 0x70, 0xc5, 0x51, 0xab,
0x56, 0xbd, 0x4b, 0xbb, 0xb4, 0x2e, 0x54, 0x3a, 0xfd, 0x23, 0x71, 0x12, 0x07, 0xf1, 0x15, 0x42, 0x6e, 0xda, 0xcc, 0xab, 0x36, 0x58, 0x83, 0x55, 0x95, 0x4b, 0xbd, 0x75, 0xa8, 0x4e, 0xea, 0xa0,
0x55, 0x6a, 0x31, 0xb3, 0x3a, 0x75, 0xb9, 0xcd, 0xb4, 0xb9, 0xca, 0x9d, 0x48, 0xc6, 0xc2, 0xfa, 0x7e, 0x45, 0x50, 0x2b, 0x95, 0x44, 0x58, 0x9b, 0x85, 0x32, 0x66, 0x36, 0xdc, 0xca, 0xdd, 0xd8,
0xb1, 0x69, 0x13, 0x77, 0x58, 0x77, 0x4e, 0xba, 0x9c, 0xe0, 0xd5, 0x2d, 0xc2, 0x70, 0x96, 0x56, 0xc6, 0xa3, 0xf6, 0x91, 0xeb, 0x43, 0xd8, 0xae, 0x06, 0xc7, 0x0d, 0x29, 0xe0, 0x55, 0x0f, 0x04,
0x7d, 0x9a, 0x96, 0xdb, 0xb7, 0x99, 0x69, 0x91, 0x09, 0x85, 0xbb, 0x67, 0x29, 0x78, 0xfa, 0x31, 0x1d, 0xe6, 0x55, 0x1d, 0xe5, 0x15, 0xb6, 0x7c, 0xe1, 0x7a, 0x30, 0xe0, 0x70, 0xef, 0x2c, 0x07,
0xb1, 0x70, 0x5a, 0xaf, 0xf6, 0x93, 0x02, 0x16, 0x77, 0xda, 0xcd, 0x87, 0xae, 0x39, 0x20, 0x2e, 0x6e, 0x1f, 0x81, 0x47, 0xb3, 0x7e, 0x95, 0xef, 0x0d, 0x34, 0xb3, 0x59, 0xdb, 0x7e, 0x14, 0xba,
0xfc, 0x0c, 0x2c, 0x70, 0x8f, 0x0c, 0xcc, 0x70, 0x59, 0xd9, 0x50, 0x36, 0x8b, 0x5b, 0xb7, 0xb4, 0x27, 0x10, 0xe2, 0x8f, 0xd0, 0xb4, 0xcc, 0xc8, 0xa1, 0x82, 0x16, 0x8d, 0x55, 0x63, 0xad, 0xb0,
0x28, 0x5d, 0x63, 0x60, 0xcd, 0x39, 0xe9, 0x72, 0x82, 0xa7, 0x71, 0x69, 0x6d, 0x70, 0x5b, 0x7b, 0x7e, 0xdb, 0x8c, 0xcb, 0xd5, 0x07, 0x36, 0x83, 0xe3, 0x86, 0x14, 0x70, 0x53, 0x5a, 0x9b, 0x27,
0xda, 0x79, 0x41, 0x74, 0xd6, 0x22, 0x0c, 0x37, 0xe0, 0x2b, 0x5f, 0x9d, 0x09, 0x7c, 0x15, 0x44, 0x77, 0xcc, 0x67, 0xf5, 0x97, 0x60, 0x8b, 0x5d, 0x10, 0xd4, 0xc2, 0x6f, 0x3a, 0xe5, 0xb1, 0x6e,
0x34, 0x34, 0x46, 0x85, 0x4f, 0x40, 0xde, 0x73, 0x88, 0x5e, 0x9e, 0x15, 0xe8, 0xd7, 0xb4, 0xe9, 0xa7, 0x8c, 0x62, 0x19, 0xe9, 0xa3, 0xe2, 0xa7, 0x28, 0xcf, 0x03, 0xb0, 0x8b, 0xe3, 0x0a, 0xfd,
0xc5, 0xd0, 0xc6, 0x6e, 0xb5, 0x1d, 0xa2, 0x37, 0x96, 0x24, 0x6c, 0x9e, 0x9f, 0x90, 0x00, 0xa9, 0xba, 0x39, 0xba, 0x19, 0x66, 0x3f, 0xad, 0x5a, 0x00, 0xb6, 0x35, 0xab, 0x61, 0xf3, 0xf2, 0x44,
0xfd, 0xa8, 0x80, 0xe5, 0xb1, 0xd4, 0x9e, 0xe9, 0x31, 0xf8, 0xe9, 0x44, 0x00, 0xda, 0xf9, 0x02, 0x14, 0x48, 0xe5, 0x3b, 0x03, 0xcd, 0xf5, 0xad, 0x76, 0x5c, 0x2e, 0xf0, 0xff, 0x07, 0x2e, 0x60,
0xe0, 0xda, 0xc2, 0xfd, 0x92, 0xb4, 0xb3, 0x30, 0xa2, 0xc4, 0x9c, 0x7f, 0x0c, 0x0a, 0x26, 0x23, 0x9e, 0xef, 0x02, 0xd2, 0x5b, 0xa5, 0xbf, 0xa0, 0xe3, 0x4c, 0xf7, 0x24, 0x89, 0xe4, 0x9f, 0xa0,
0x96, 0x57, 0x9e, 0xdd, 0xc8, 0x6d, 0x16, 0xb7, 0xde, 0x3b, 0x97, 0xf7, 0x8d, 0x65, 0x89, 0x58, 0x09, 0x57, 0x80, 0xc7, 0x8b, 0xe3, 0xab, 0xb9, 0xb5, 0xc2, 0xfa, 0x3f, 0xce, 0x95, 0xbd, 0x35,
0x68, 0x72, 0x5d, 0x14, 0x42, 0xd4, 0xfe, 0x9a, 0x8d, 0xf9, 0xce, 0x63, 0x82, 0xf7, 0xc1, 0x15, 0xa7, 0x11, 0x27, 0xb6, 0xa5, 0x2f, 0x89, 0x20, 0x2a, 0x5f, 0xe5, 0x13, 0xb9, 0xcb, 0x3b, 0xe1,
0xcc, 0x18, 0xd6, 0x8f, 0x11, 0x79, 0xd9, 0x37, 0x5d, 0x62, 0x88, 0x08, 0x16, 0x1a, 0x30, 0xf0, 0x07, 0xe8, 0x0a, 0x15, 0x82, 0xda, 0x47, 0x04, 0x5e, 0xb5, 0xdc, 0x10, 0x1c, 0x75, 0x83, 0x69,
0xd5, 0x2b, 0xdb, 0x09, 0x0e, 0x4a, 0x49, 0x72, 0x5d, 0x87, 0x1a, 0x4d, 0xfb, 0x88, 0x3e, 0xb5, 0x0b, 0x77, 0x3b, 0xe5, 0x2b, 0x1b, 0x29, 0x0d, 0xc9, 0x58, 0x4a, 0xdf, 0x80, 0x39, 0xdb, 0xfe,
0x5b, 0xb4, 0x6f, 0x33, 0x91, 0x60, 0xa9, 0x7b, 0x90, 0xe0, 0xa0, 0x94, 0x24, 0xd4, 0xc1, 0xfa, 0x21, 0x7b, 0xe6, 0xef, 0xb2, 0x96, 0x2f, 0x54, 0x81, 0xb5, 0xef, 0x7e, 0x4a, 0x43, 0x32, 0x96,
0x80, 0xf6, 0xfa, 0x16, 0xd9, 0x33, 0x8f, 0x88, 0x3e, 0xd4, 0x7b, 0xa4, 0x45, 0x0d, 0xe2, 0x95, 0xd8, 0x46, 0xcb, 0x27, 0xac, 0xd9, 0xf2, 0x60, 0xc7, 0x3d, 0x04, 0xbb, 0x6d, 0x37, 0x61, 0x97,
0x73, 0x1b, 0xb9, 0xcd, 0xc5, 0x46, 0x3d, 0xf0, 0xd5, 0xf5, 0x67, 0x19, 0xfc, 0x53, 0x5f, 0x5d, 0x39, 0xc0, 0x8b, 0xb9, 0xd5, 0xdc, 0xda, 0x8c, 0x55, 0xed, 0x76, 0xca, 0xcb, 0xcf, 0x87, 0xe8,
0xcb, 0xa0, 0xa3, 0x4c, 0x30, 0xf8, 0x00, 0xac, 0xc8, 0x0c, 0xed, 0x60, 0x07, 0xeb, 0x26, 0x1b, 0x4f, 0x3b, 0xe5, 0xa5, 0x21, 0x72, 0x32, 0x14, 0x0c, 0x3f, 0x44, 0xf3, 0xba, 0x42, 0x9b, 0x34,
0x96, 0xf3, 0xc2, 0xc3, 0xb5, 0xc0, 0x57, 0x57, 0xda, 0x49, 0x16, 0x4a, 0xcb, 0xc2, 0x47, 0x60, 0xa0, 0xb6, 0x2b, 0xda, 0xc5, 0xbc, 0xca, 0x70, 0xa9, 0xdb, 0x29, 0xcf, 0xd7, 0xd2, 0x2a, 0x92,
0xf9, 0xc8, 0xfb, 0xc8, 0xa5, 0x7d, 0xe7, 0x80, 0xf6, 0x4c, 0x7d, 0x58, 0x2e, 0x6c, 0x28, 0x9b, 0xb5, 0xc5, 0x8f, 0xd1, 0xdc, 0x21, 0xff, 0x4f, 0xc8, 0x5a, 0xc1, 0x3e, 0x6b, 0xba, 0x76, 0xbb,
0x8b, 0x8d, 0x5a, 0xe0, 0xab, 0xcb, 0x1f, 0xb6, 0x63, 0x8c, 0xd3, 0x34, 0x01, 0x25, 0x15, 0x6b, 0x38, 0xb1, 0x6a, 0xac, 0xcd, 0x58, 0x95, 0x6e, 0xa7, 0x3c, 0xf7, 0xef, 0x5a, 0x42, 0x71, 0x9a,
0x3f, 0x28, 0x60, 0x7e, 0xa7, 0xdd, 0xdc, 0xa7, 0x06, 0xb9, 0x84, 0x76, 0x6f, 0x26, 0xda, 0xfd, 0x15, 0x90, 0xb4, 0x23, 0x06, 0x34, 0x27, 0xd8, 0x31, 0xf8, 0xb2, 0x74, 0xc0, 0x05, 0x2f, 0x4e,
0xea, 0x19, 0x0d, 0xc3, 0x9d, 0x9a, 0xda, 0xec, 0x7f, 0x86, 0xcd, 0xce, 0x65, 0xe4, 0xb4, 0x6e, 0xaa, 0x5e, 0xae, 0x7d, 0xa8, 0x97, 0x07, 0x09, 0x07, 0xeb, 0xaa, 0x6e, 0xe7, 0x5c, 0x52, 0xca,
0x80, 0xbc, 0x8d, 0x2d, 0x22, 0x5c, 0x5f, 0x8c, 0x74, 0xf6, 0xb1, 0x45, 0x90, 0xe0, 0xc0, 0xf7, 0x49, 0x1a, 0x15, 0x6f, 0xa2, 0xc5, 0x30, 0x6a, 0x0e, 0x27, 0x10, 0xb4, 0xea, 0x4d, 0x97, 0x1f,
0xc1, 0x9c, 0x4d, 0x0d, 0xd2, 0x7c, 0x28, 0x1c, 0x58, 0x6c, 0x5c, 0x91, 0x32, 0x73, 0xfb, 0x82, 0x15, 0xa7, 0xd4, 0x8d, 0xaf, 0x76, 0x3b, 0xe5, 0x45, 0x92, 0x55, 0x92, 0x41, 0xfb, 0xca, 0xb7,
0x8a, 0x24, 0x17, 0xde, 0x01, 0x4b, 0x8c, 0x3a, 0xb4, 0x47, 0xbb, 0xc3, 0x27, 0x64, 0x38, 0x2a, 0x06, 0x9a, 0xda, 0xac, 0x6d, 0xef, 0x31, 0x07, 0x2e, 0xe1, 0x69, 0x6e, 0xa7, 0x9e, 0xe6, 0xb5,
0x7d, 0x29, 0xf0, 0xd5, 0xa5, 0xc3, 0x18, 0x1d, 0x25, 0xa4, 0x60, 0x07, 0x14, 0x71, 0xaf, 0x47, 0x33, 0x86, 0x5b, 0x26, 0x35, 0xf2, 0x61, 0xfe, 0x16, 0x3d, 0x4c, 0x69, 0xa3, 0x99, 0x65, 0x15,
0x75, 0xcc, 0x70, 0xa7, 0x47, 0x44, 0x3d, 0x8b, 0x5b, 0xf5, 0x77, 0xc5, 0x18, 0xf6, 0x0b, 0x37, 0xe5, 0x7d, 0xea, 0x81, 0x4a, 0x7d, 0x26, 0xf6, 0xd9, 0xa3, 0x1e, 0x10, 0xa5, 0xc1, 0xff, 0x44,
0x8e, 0x88, 0x47, 0xfb, 0xae, 0x4e, 0xbc, 0xc6, 0x4a, 0xe0, 0xab, 0xc5, 0xed, 0x08, 0x07, 0xc5, 0x93, 0x3e, 0x73, 0x60, 0xfb, 0x91, 0x4a, 0x60, 0xc6, 0xba, 0xa2, 0x6d, 0x26, 0xf7, 0x94, 0x94,
0x41, 0x6b, 0xdf, 0x2b, 0xa0, 0x28, 0xa3, 0xbe, 0x84, 0x01, 0x7f, 0x94, 0x1c, 0xf0, 0xff, 0x9f, 0x68, 0x2d, 0xbe, 0x8b, 0x66, 0x05, 0x0b, 0x58, 0x93, 0x35, 0xda, 0x4f, 0xa1, 0xdd, 0x1b, 0xd3,
0xa3, 0x5e, 0x53, 0xc6, 0x5b, 0x1f, 0xbb, 0x2d, 0x66, 0xfb, 0x10, 0xcc, 0x1b, 0xa2, 0x68, 0x5e, 0x85, 0x6e, 0xa7, 0x3c, 0x7b, 0x90, 0x90, 0x93, 0x94, 0x15, 0xae, 0xa3, 0x02, 0x6d, 0x36, 0x99,
0x59, 0x11, 0xd0, 0xd7, 0xce, 0x01, 0x2d, 0xf7, 0xc7, 0x8a, 0x34, 0x30, 0x1f, 0x9e, 0x3d, 0x34, 0x4d, 0x05, 0xad, 0x37, 0x41, 0xcd, 0x5e, 0x61, 0xbd, 0xfa, 0xa1, 0x3b, 0x46, 0xb3, 0x2d, 0x83,
0x82, 0xaa, 0x7d, 0x33, 0x07, 0x96, 0x46, 0xa3, 0xd3, 0xc3, 0x9e, 0x77, 0x09, 0x0d, 0xfd, 0x01, 0x13, 0xe0, 0xac, 0x15, 0xda, 0xc0, 0xad, 0xf9, 0x6e, 0xa7, 0x5c, 0xd8, 0x88, 0x71, 0x48, 0x12,
0x28, 0x3a, 0x2e, 0x1d, 0x98, 0x9e, 0x49, 0x6d, 0xe2, 0xca, 0xb6, 0x5a, 0x93, 0x2a, 0xc5, 0x83, 0xb4, 0xf2, 0x8d, 0x81, 0x0a, 0xfa, 0xd6, 0x97, 0x40, 0x46, 0x8f, 0xd3, 0x64, 0xf4, 0xf7, 0x73,
0x88, 0x85, 0xe2, 0x72, 0xb0, 0x07, 0x80, 0x83, 0x5d, 0x6c, 0x11, 0xc6, 0x53, 0x90, 0x13, 0x29, 0xf4, 0x6b, 0x04, 0x15, 0xd9, 0xfd, 0xb4, 0x15, 0x0f, 0x1d, 0xa0, 0x29, 0x47, 0x35, 0x8d, 0x17,
0xb8, 0xf7, 0xae, 0x14, 0xc4, 0xc3, 0xd2, 0x0e, 0xc6, 0xaa, 0xbb, 0x36, 0x73, 0x87, 0x91, 0x8b, 0x0d, 0x05, 0x7d, 0xfd, 0x1c, 0xd0, 0x9a, 0xeb, 0xe6, 0x75, 0x80, 0xa9, 0xe8, 0xcc, 0x49, 0x0f,
0x11, 0x03, 0xc5, 0xf0, 0xe1, 0x09, 0x58, 0x76, 0x89, 0xde, 0xc3, 0xa6, 0x25, 0xb7, 0x45, 0x5e, 0xaa, 0xf2, 0xc5, 0x24, 0x9a, 0xed, 0x3d, 0xf3, 0x26, 0xe5, 0xfc, 0x12, 0x06, 0xfa, 0x5f, 0xa8,
0xb8, 0xb9, 0xcb, 0xb7, 0x05, 0x8a, 0x33, 0x4e, 0x7d, 0xf5, 0xd6, 0xe4, 0x1d, 0xae, 0x1d, 0x10, 0x10, 0x84, 0xec, 0xc4, 0xe5, 0x2e, 0xf3, 0x21, 0xd4, 0x63, 0xb5, 0xa4, 0x5d, 0x0a, 0xfb, 0xb1,
0xd7, 0x33, 0x3d, 0x46, 0x6c, 0x16, 0x36, 0x6c, 0x42, 0x07, 0x25, 0xb1, 0xf9, 0xec, 0x58, 0x7c, 0x8a, 0x24, 0xed, 0x70, 0x13, 0xa1, 0x80, 0x86, 0xd4, 0x03, 0x21, 0x4b, 0x90, 0x53, 0x25, 0xb8,
0x8f, 0x3e, 0x75, 0x98, 0x49, 0x6d, 0xaf, 0x5c, 0x88, 0x66, 0xa7, 0x15, 0xa3, 0xa3, 0x84, 0x14, 0xff, 0xa1, 0x12, 0x24, 0xaf, 0x65, 0xee, 0xf7, 0x5d, 0xb7, 0x7c, 0x11, 0xb6, 0xe3, 0x14, 0x63,
0xdc, 0x03, 0xeb, 0xbc, 0xcd, 0x3f, 0x0f, 0x0d, 0xec, 0x7e, 0xe1, 0x60, 0x9b, 0xa7, 0xaa, 0x3c, 0x05, 0x49, 0xe0, 0xe3, 0x63, 0x34, 0x17, 0x82, 0xdd, 0xa4, 0xae, 0xa7, 0x99, 0x2d, 0xaf, 0xd2,
0x27, 0x96, 0x62, 0x99, 0x2f, 0xdd, 0xed, 0x0c, 0x3e, 0xca, 0xd4, 0x82, 0x9f, 0x80, 0xd5, 0x70, 0xdc, 0x92, 0x0c, 0x43, 0x92, 0x8a, 0xd3, 0x4e, 0xf9, 0xf6, 0xe0, 0xf7, 0x86, 0xb9, 0x0f, 0x21,
0xeb, 0x36, 0x4c, 0xdb, 0x30, 0xed, 0x2e, 0xdf, 0xb9, 0xe5, 0x79, 0x11, 0xf4, 0xf5, 0xc0, 0x57, 0x77, 0xb9, 0x00, 0x5f, 0x44, 0x03, 0x9b, 0xf2, 0x21, 0x69, 0x6c, 0xf9, 0x76, 0x3c, 0xc9, 0xf9,
0x57, 0x9f, 0xa5, 0x99, 0xa7, 0x59, 0x44, 0x34, 0x09, 0x02, 0x5f, 0x82, 0x55, 0x61, 0x91, 0x18, 0xcf, 0x02, 0xe1, 0x32, 0x9f, 0x17, 0x27, 0xe2, 0xb7, 0xb3, 0x9b, 0x90, 0x93, 0x94, 0x15, 0xde,
0x72, 0x11, 0x98, 0xc4, 0x2b, 0x2f, 0x88, 0xfa, 0x6d, 0xc6, 0xeb, 0xc7, 0x53, 0xc7, 0x1b, 0x69, 0x41, 0xcb, 0x72, 0xcc, 0x3f, 0x8e, 0x02, 0x6c, 0xbd, 0x0e, 0xa8, 0x2f, 0x4b, 0x55, 0x9c, 0x54,
0xb4, 0x2e, 0xda, 0xa4, 0x47, 0x74, 0x46, 0xdd, 0x43, 0xe2, 0x5a, 0x8d, 0xff, 0xc9, 0x7a, 0xad, 0x74, 0x56, 0x94, 0x0b, 0x62, 0x63, 0x88, 0x9e, 0x0c, 0xf5, 0xc2, 0xff, 0x43, 0x8b, 0xd1, 0x86,
0x6e, 0xa7, 0xa1, 0xd0, 0x24, 0x7a, 0xe5, 0x01, 0x58, 0x49, 0x15, 0x1c, 0x96, 0x40, 0xee, 0x84, 0xb0, 0x5c, 0xdf, 0x71, 0xfd, 0x86, 0xdc, 0x0f, 0x8a, 0x19, 0x67, 0xac, 0x1b, 0x92, 0x19, 0x9f,
0x0c, 0xc3, 0x45, 0x87, 0xf8, 0x27, 0x5c, 0x07, 0x85, 0x01, 0xee, 0xf5, 0x49, 0xd8, 0x81, 0x28, 0x67, 0x95, 0xa7, 0xc3, 0x84, 0x64, 0x10, 0x04, 0xbf, 0x42, 0x8b, 0x2a, 0x22, 0x38, 0x9a, 0x08,
0x3c, 0xdc, 0x9f, 0xbd, 0xa7, 0xd4, 0x7e, 0x56, 0x40, 0x29, 0xde, 0x3d, 0x97, 0xb0, 0x36, 0x5a, 0x5c, 0xe0, 0xc5, 0xe9, 0x41, 0x7a, 0x97, 0xa5, 0x93, 0x83, 0xd4, 0xa3, 0x8b, 0x1a, 0x34, 0xc1,
0xc9, 0xb5, 0xb1, 0x79, 0xde, 0xc6, 0x9e, 0xb2, 0x3b, 0xbe, 0x9b, 0x05, 0xa5, 0xb0, 0x38, 0xe1, 0x16, 0x2c, 0x3c, 0x80, 0xd0, 0xb3, 0xfe, 0xa6, 0xfb, 0xb5, 0xb8, 0x91, 0x85, 0x22, 0x83, 0xe8,
0xad, 0x6f, 0x11, 0x9b, 0x5d, 0xc2, 0x68, 0xa3, 0xc4, 0x5d, 0x75, 0xeb, 0xec, 0x3d, 0x1e, 0x79, 0x2b, 0x0f, 0xd1, 0x7c, 0xa6, 0xe1, 0x78, 0x01, 0xe5, 0x8e, 0xa1, 0x1d, 0x11, 0x1d, 0x91, 0x3f,
0x37, 0xed, 0xd2, 0x82, 0xcf, 0xc1, 0x9c, 0xc7, 0x30, 0xeb, 0xf3, 0x99, 0xe7, 0xa8, 0x5b, 0x17, 0xf1, 0x32, 0x9a, 0x38, 0xa1, 0xcd, 0x16, 0x44, 0x13, 0x48, 0xa2, 0xc3, 0x83, 0xf1, 0xfb, 0x46,
0x42, 0x15, 0x9a, 0xd1, 0xa5, 0x15, 0x9e, 0x91, 0x44, 0xac, 0xfd, 0xa2, 0x80, 0xf5, 0xb4, 0xca, 0xe5, 0x07, 0x03, 0x2d, 0x24, 0xa7, 0xe7, 0x12, 0x68, 0x63, 0x37, 0x4d, 0x1b, 0x6b, 0xe7, 0x1d,
0x25, 0x14, 0xfb, 0xe3, 0x64, 0xb1, 0x6f, 0x5c, 0x24, 0xa2, 0x29, 0x05, 0xff, 0x4d, 0x01, 0xff, 0xec, 0x11, 0xdc, 0xf1, 0xa9, 0x81, 0x66, 0x93, 0x8b, 0x10, 0xdf, 0x44, 0xd3, 0xb4, 0xe5, 0xb8,
0x99, 0x08, 0x5e, 0x5c, 0x8f, 0x7c, 0x4f, 0x38, 0xa9, 0x6d, 0xb4, 0x1f, 0xdd, 0xf9, 0x62, 0x4f, 0xe0, 0xdb, 0x3d, 0xb2, 0xef, 0x67, 0xb3, 0xa1, 0xe5, 0xa4, 0x6f, 0x21, 0xd7, 0x24, 0xbc, 0x0e,
0x1c, 0x64, 0xf0, 0x51, 0xa6, 0x16, 0x7c, 0x01, 0x4a, 0xa6, 0xdd, 0x33, 0x6d, 0x12, 0xd2, 0xda, 0xdc, 0x90, 0xca, 0x49, 0xab, 0x81, 0xcd, 0x7c, 0x87, 0xab, 0x32, 0xe5, 0xa2, 0x35, 0xb9, 0x95,
0x51, 0xb9, 0x33, 0x87, 0x39, 0x8d, 0x2c, 0xca, 0xbc, 0x1e, 0xf8, 0x6a, 0xa9, 0x99, 0x42, 0x41, 0x55, 0x92, 0x41, 0xfb, 0xca, 0xd7, 0xe3, 0x68, 0x21, 0x1a, 0x90, 0xe8, 0x2b, 0xc9, 0x03, 0x5f,
0x13, 0xb8, 0xb5, 0x5f, 0x33, 0xca, 0x23, 0xee, 0xc2, 0x1b, 0x60, 0x21, 0x7c, 0xbd, 0x12, 0x57, 0x5c, 0x02, 0xbd, 0x90, 0xd4, 0xbe, 0xbc, 0x7d, 0xf6, 0x2e, 0x89, 0xb3, 0x1b, 0xb5, 0x38, 0xf1,
0x86, 0x31, 0x4e, 0xf7, 0xb6, 0xa4, 0xa3, 0xb1, 0x84, 0xe8, 0x20, 0x91, 0x0a, 0xe9, 0xe8, 0xc5, 0x0b, 0x34, 0xc9, 0x05, 0x15, 0x2d, 0xc9, 0x3b, 0x12, 0x75, 0xfd, 0x42, 0xa8, 0xca, 0x33, 0x5e,
0x3a, 0x48, 0x68, 0xc6, 0x3a, 0x48, 0x9c, 0x91, 0x44, 0xe4, 0x9e, 0xf0, 0x07, 0x90, 0x48, 0x68, 0x9c, 0xd1, 0x99, 0x68, 0xc4, 0xca, 0x8f, 0x06, 0x5a, 0xce, 0xba, 0x5c, 0xc2, 0xc0, 0xfd, 0x37,
0x2e, 0xe9, 0xc9, 0xbe, 0xa4, 0xa3, 0xb1, 0x44, 0xed, 0xef, 0x5c, 0x46, 0x95, 0x44, 0x2b, 0xc6, 0x3d, 0x70, 0x37, 0x2f, 0x72, 0xa3, 0x11, 0x43, 0xf7, 0xb3, 0x81, 0xfe, 0x32, 0x70, 0x79, 0xb5,
0x42, 0x1a, 0x3d, 0xda, 0xd3, 0x21, 0x19, 0xe3, 0x90, 0x0c, 0xf8, 0xad, 0x02, 0x20, 0x1e, 0x43, 0xa2, 0x25, 0x57, 0x05, 0x19, 0x46, 0xdc, 0x8b, 0xbf, 0x3b, 0x14, 0x57, 0xed, 0x0f, 0xd1, 0x93,
0xb4, 0x46, 0xad, 0x1a, 0xf6, 0xd3, 0xe3, 0x8b, 0x4f, 0x88, 0xb6, 0x3d, 0x01, 0x16, 0xde, 0x93, 0xa1, 0x5e, 0xf8, 0x25, 0x5a, 0x70, 0xfd, 0xa6, 0xeb, 0x43, 0x24, 0xab, 0xc5, 0xed, 0x1e, 0x4a,
0x15, 0xe9, 0x04, 0x9c, 0x14, 0x40, 0x19, 0x1e, 0x40, 0x13, 0x14, 0x43, 0xea, 0xae, 0xeb, 0x52, 0x28, 0x59, 0x64, 0xd5, 0xe6, 0xe5, 0x6e, 0xa7, 0xbc, 0xb0, 0x9d, 0x41, 0x21, 0x03, 0xb8, 0x95,
0x57, 0x8e, 0xec, 0xd5, 0xb3, 0x1d, 0x12, 0xe2, 0x8d, 0xaa, 0x78, 0xc8, 0x45, 0xfa, 0xa7, 0xbe, 0x9f, 0x86, 0xb4, 0x47, 0xed, 0x63, 0xf9, 0xa2, 0x94, 0x04, 0xc2, 0x81, 0x17, 0xa5, 0xe5, 0xa4,
0x5a, 0x8c, 0xf1, 0x51, 0x1c, 0x9b, 0x9b, 0x32, 0x48, 0x64, 0x2a, 0xff, 0x2f, 0x4c, 0x3d, 0x24, 0x6f, 0xa1, 0x26, 0x48, 0x95, 0x42, 0x27, 0x7a, 0xb1, 0x09, 0x52, 0x9e, 0x89, 0x09, 0x52, 0x67,
0xd3, 0x4d, 0xc5, 0xb0, 0x2b, 0xbb, 0xe0, 0xbf, 0x53, 0x12, 0x74, 0xa1, 0x7b, 0xe5, 0x2b, 0x05, 0xa2, 0x11, 0x65, 0x26, 0xf2, 0x23, 0x4c, 0x15, 0x34, 0x97, 0xce, 0x64, 0x4f, 0xcb, 0x49, 0xdf,
0xc4, 0x6d, 0xc0, 0x3d, 0x90, 0xe7, 0x3f, 0xd6, 0x72, 0xc3, 0x5c, 0x3f, 0xdf, 0x86, 0x39, 0x34, 0xa2, 0xf2, 0x7b, 0x6e, 0x48, 0x97, 0xd4, 0x28, 0x26, 0xae, 0xd4, 0xfb, 0x93, 0x93, 0xbd, 0x92,
0x2d, 0x12, 0x2d, 0x4a, 0x7e, 0x42, 0x02, 0x05, 0x5e, 0x03, 0xf3, 0x16, 0xf1, 0x3c, 0xdc, 0x95, 0xd3, 0xbf, 0x92, 0x83, 0xbf, 0x34, 0x10, 0xa6, 0x7d, 0x88, 0xdd, 0xde, 0xa8, 0x46, 0xf3, 0xf4,
0x96, 0xa3, 0x57, 0x5f, 0x2b, 0x24, 0xa3, 0x11, 0xbf, 0x76, 0x17, 0xac, 0x65, 0xbc, 0xa3, 0xa1, 0xe4, 0xe2, 0x2f, 0xc4, 0xdc, 0x18, 0x00, 0x8b, 0x76, 0xf5, 0x8a, 0x4e, 0x02, 0x0f, 0x1a, 0x90,
0x0a, 0x0a, 0xba, 0xf8, 0xf3, 0xe3, 0x0e, 0x15, 0x1a, 0x8b, 0x7c, 0xcb, 0xec, 0x88, 0x1f, 0xbe, 0x21, 0x19, 0x60, 0x17, 0x15, 0x22, 0xe9, 0x56, 0x18, 0xb2, 0x50, 0x3f, 0xd9, 0x6b, 0x67, 0x27,
0x90, 0xde, 0xb8, 0xf9, 0xea, 0x6d, 0x75, 0xe6, 0xf5, 0xdb, 0xea, 0xcc, 0x9b, 0xb7, 0xd5, 0x99, 0xa4, 0xcc, 0xad, 0x92, 0xfa, 0x98, 0x8c, 0xfd, 0x4f, 0x3b, 0xe5, 0x42, 0x42, 0x4f, 0x92, 0xd8,
0x2f, 0x83, 0xaa, 0xf2, 0x2a, 0xa8, 0x2a, 0xaf, 0x83, 0xaa, 0xf2, 0x26, 0xa8, 0x2a, 0xbf, 0x07, 0x32, 0x94, 0x03, 0x71, 0xa8, 0xfc, 0x9f, 0x08, 0xf5, 0x08, 0x46, 0x87, 0x4a, 0x60, 0xaf, 0x6c,
0x55, 0xe5, 0xeb, 0x3f, 0xaa, 0x33, 0xcf, 0xe7, 0x65, 0xbe, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0xa1, 0xbf, 0x8e, 0x28, 0xd0, 0x85, 0x76, 0xdb, 0x67, 0x06, 0x4a, 0xc6, 0xc0, 0x3b, 0x28, 0x2f,
0x4b, 0x3f, 0x49, 0x6e, 0x6d, 0x11, 0x00, 0x00, 0x5c, 0xfd, 0x12, 0x0b, 0xeb, 0x37, 0xce, 0xc7, 0x30, 0x07, 0xae, 0x07, 0x31, 0x51, 0xca, 0x13,
0x51, 0x28, 0xf8, 0x3a, 0x9a, 0xf2, 0x80, 0x73, 0xda, 0xd0, 0x91, 0xe3, 0x2f, 0xcf, 0xdd, 0x48,
0x4c, 0x7a, 0xfa, 0xca, 0x3d, 0xb4, 0x34, 0xe4, 0x5b, 0x1e, 0x97, 0xd1, 0x84, 0xad, 0xfe, 0x29,
0xcb, 0x84, 0x26, 0xac, 0x19, 0xc9, 0x32, 0x9b, 0xea, 0x0f, 0x72, 0x24, 0xb7, 0x6e, 0xbd, 0x79,
0x5f, 0x1a, 0x7b, 0xfb, 0xbe, 0x34, 0xf6, 0xee, 0x7d, 0x69, 0xec, 0x93, 0x6e, 0xc9, 0x78, 0xd3,
0x2d, 0x19, 0x6f, 0xbb, 0x25, 0xe3, 0x5d, 0xb7, 0x64, 0xfc, 0xd2, 0x2d, 0x19, 0x9f, 0xff, 0x5a,
0x1a, 0x7b, 0x31, 0xa5, 0xeb, 0xfd, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6a, 0xb1, 0x9d, 0x65,
0x9d, 0x12, 0x00, 0x00,
} }
func (m *CSIDriver) Marshal() (dAtA []byte, err error) { func (m *CSIDriver) Marshal() (dAtA []byte, err error) {
@ -721,6 +757,30 @@ func (m *CSIDriverSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.RequiresRepublish != nil {
i--
if *m.RequiresRepublish {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x38
}
if len(m.TokenRequests) > 0 {
for iNdEx := len(m.TokenRequests) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.TokenRequests[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x32
}
}
if m.FSGroupPolicy != nil { if m.FSGroupPolicy != nil {
i -= len(*m.FSGroupPolicy) i -= len(*m.FSGroupPolicy)
copy(dAtA[i:], *m.FSGroupPolicy) copy(dAtA[i:], *m.FSGroupPolicy)
@ -1107,6 +1167,39 @@ func (m *StorageClassList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *TokenRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TokenRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.ExpirationSeconds != nil {
i = encodeVarintGenerated(dAtA, i, uint64(*m.ExpirationSeconds))
i--
dAtA[i] = 0x10
}
i -= len(m.Audience)
copy(dAtA[i:], m.Audience)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Audience)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func (m *VolumeAttachment) Marshal() (dAtA []byte, err error) { func (m *VolumeAttachment) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
@ -1503,6 +1596,15 @@ func (m *CSIDriverSpec) Size() (n int) {
l = len(*m.FSGroupPolicy) l = len(*m.FSGroupPolicy)
n += 1 + l + sovGenerated(uint64(l)) n += 1 + l + sovGenerated(uint64(l))
} }
if len(m.TokenRequests) > 0 {
for _, e := range m.TokenRequests {
l = e.Size()
n += 1 + l + sovGenerated(uint64(l))
}
}
if m.RequiresRepublish != nil {
n += 2
}
return n return n
} }
@ -1635,6 +1737,20 @@ func (m *StorageClassList) Size() (n int) {
return n return n
} }
func (m *TokenRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Audience)
n += 1 + l + sovGenerated(uint64(l))
if m.ExpirationSeconds != nil {
n += 1 + sovGenerated(uint64(*m.ExpirationSeconds))
}
return n
}
func (m *VolumeAttachment) Size() (n int) { func (m *VolumeAttachment) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
@ -1787,12 +1903,19 @@ func (this *CSIDriverSpec) String() string {
if this == nil { if this == nil {
return "nil" return "nil"
} }
repeatedStringForTokenRequests := "[]TokenRequest{"
for _, f := range this.TokenRequests {
repeatedStringForTokenRequests += strings.Replace(strings.Replace(f.String(), "TokenRequest", "TokenRequest", 1), `&`, ``, 1) + ","
}
repeatedStringForTokenRequests += "}"
s := strings.Join([]string{`&CSIDriverSpec{`, s := strings.Join([]string{`&CSIDriverSpec{`,
`AttachRequired:` + valueToStringGenerated(this.AttachRequired) + `,`, `AttachRequired:` + valueToStringGenerated(this.AttachRequired) + `,`,
`PodInfoOnMount:` + valueToStringGenerated(this.PodInfoOnMount) + `,`, `PodInfoOnMount:` + valueToStringGenerated(this.PodInfoOnMount) + `,`,
`VolumeLifecycleModes:` + fmt.Sprintf("%v", this.VolumeLifecycleModes) + `,`, `VolumeLifecycleModes:` + fmt.Sprintf("%v", this.VolumeLifecycleModes) + `,`,
`StorageCapacity:` + valueToStringGenerated(this.StorageCapacity) + `,`, `StorageCapacity:` + valueToStringGenerated(this.StorageCapacity) + `,`,
`FSGroupPolicy:` + valueToStringGenerated(this.FSGroupPolicy) + `,`, `FSGroupPolicy:` + valueToStringGenerated(this.FSGroupPolicy) + `,`,
`TokenRequests:` + repeatedStringForTokenRequests + `,`,
`RequiresRepublish:` + valueToStringGenerated(this.RequiresRepublish) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@ -1900,6 +2023,17 @@ func (this *StorageClassList) String() string {
}, "") }, "")
return s return s
} }
func (this *TokenRequest) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&TokenRequest{`,
`Audience:` + fmt.Sprintf("%v", this.Audience) + `,`,
`ExpirationSeconds:` + valueToStringGenerated(this.ExpirationSeconds) + `,`,
`}`,
}, "")
return s
}
func (this *VolumeAttachment) String() string { func (this *VolumeAttachment) String() string {
if this == nil { if this == nil {
return "nil" return "nil"
@ -2399,6 +2533,61 @@ func (m *CSIDriverSpec) Unmarshal(dAtA []byte) error {
s := FSGroupPolicy(dAtA[iNdEx:postIndex]) s := FSGroupPolicy(dAtA[iNdEx:postIndex])
m.FSGroupPolicy = &s m.FSGroupPolicy = &s
iNdEx = postIndex iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TokenRequests", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.TokenRequests = append(m.TokenRequests, TokenRequest{})
if err := m.TokenRequests[len(m.TokenRequests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RequiresRepublish", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
b := bool(v != 0)
m.RequiresRepublish = &b
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:]) skippy, err := skipGenerated(dAtA[iNdEx:])
@ -3452,6 +3641,111 @@ func (m *StorageClassList) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *TokenRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TokenRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TokenRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Audience", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Audience = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ExpirationSeconds", wireType)
}
var v int64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.ExpirationSeconds = &v
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *VolumeAttachment) Unmarshal(dAtA []byte) error { func (m *VolumeAttachment) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0

View File

@ -147,6 +147,43 @@ message CSIDriverSpec {
// that enable the CSIVolumeFSGroupPolicy feature gate. // that enable the CSIVolumeFSGroupPolicy feature gate.
// +optional // +optional
optional string fsGroupPolicy = 5; optional string fsGroupPolicy = 5;
// TokenRequests indicates the CSI driver needs pods' service account
// tokens it is mounting volume for to do necessary authentication. Kubelet
// will pass the tokens in VolumeContext in the CSI NodePublishVolume calls.
// The CSI driver should parse and validate the following VolumeContext:
// "csi.storage.k8s.io/serviceAccount.tokens": {
// "<audience>": {
// "token": <token>,
// "expirationTimestamp": <expiration timestamp in RFC3339>,
// },
// ...
// }
//
// Note: Audience in each TokenRequest should be different and at
// most one token is empty string. To receive a new token after expiry,
// RequiresRepublish can be used to trigger NodePublishVolume periodically.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
// +listType=atomic
repeated TokenRequest tokenRequests = 6;
// RequiresRepublish indicates the CSI driver wants `NodePublishVolume`
// being periodically called to reflect any possible change in the mounted
// volume. This field defaults to false.
//
// Note: After a successful initial NodePublishVolume call, subsequent calls
// to NodePublishVolume should only update the contents of the volume. New
// mount points will not be seen by a running container.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
optional bool requiresRepublish = 7;
} }
// DEPRECATED - This group version of CSINode is deprecated by storage/v1/CSINode. // DEPRECATED - This group version of CSINode is deprecated by storage/v1/CSINode.
@ -283,6 +320,19 @@ message StorageClassList {
repeated StorageClass items = 2; repeated StorageClass items = 2;
} }
// TokenRequest contains parameters of a service account token.
message TokenRequest {
// Audience is the intended audience of the token in "TokenRequestSpec".
// It will default to the audiences of kube apiserver.
optional string audience = 1;
// ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec".
// It has the same default value of "ExpirationSeconds" in "TokenRequestSpec"
//
// +optional
optional int64 expirationSeconds = 2;
}
// VolumeAttachment captures the intent to attach or detach the specified volume // VolumeAttachment captures the intent to attach or detach the specified volume
// to/from the specified node. // to/from the specified node.
// //

View File

@ -364,6 +364,43 @@ type CSIDriverSpec struct {
// that enable the CSIVolumeFSGroupPolicy feature gate. // that enable the CSIVolumeFSGroupPolicy feature gate.
// +optional // +optional
FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"` FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"`
// TokenRequests indicates the CSI driver needs pods' service account
// tokens it is mounting volume for to do necessary authentication. Kubelet
// will pass the tokens in VolumeContext in the CSI NodePublishVolume calls.
// The CSI driver should parse and validate the following VolumeContext:
// "csi.storage.k8s.io/serviceAccount.tokens": {
// "<audience>": {
// "token": <token>,
// "expirationTimestamp": <expiration timestamp in RFC3339>,
// },
// ...
// }
//
// Note: Audience in each TokenRequest should be different and at
// most one token is empty string. To receive a new token after expiry,
// RequiresRepublish can be used to trigger NodePublishVolume periodically.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
// +listType=atomic
TokenRequests []TokenRequest `json:"tokenRequests,omitempty" protobuf:"bytes,6,opt,name=tokenRequests"`
// RequiresRepublish indicates the CSI driver wants `NodePublishVolume`
// being periodically called to reflect any possible change in the mounted
// volume. This field defaults to false.
//
// Note: After a successful initial NodePublishVolume call, subsequent calls
// to NodePublishVolume should only update the contents of the volume. New
// mount points will not be seen by a running container.
//
// This is an alpha feature and only available when the
// CSIServiceAccountToken feature is enabled.
//
// +optional
RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"`
} }
// FSGroupPolicy specifies if a CSI Driver supports modifying // FSGroupPolicy specifies if a CSI Driver supports modifying
@ -395,6 +432,20 @@ const (
// provided by a CSI driver. More modes may be added in the future. // provided by a CSI driver. More modes may be added in the future.
type VolumeLifecycleMode string type VolumeLifecycleMode string
// TokenRequest contains parameters of a service account token.
type TokenRequest struct {
// Audience is the intended audience of the token in "TokenRequestSpec".
// It will default to the audiences of kube apiserver.
//
Audience string `json:"audience" protobuf:"bytes,1,opt,name=audience"`
// ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec".
// It has the same default value of "ExpirationSeconds" in "TokenRequestSpec"
//
// +optional
ExpirationSeconds *int64 `json:"expirationSeconds,omitempty" protobuf:"varint,2,opt,name=expirationSeconds"`
}
const ( const (
// VolumeLifecyclePersistent explicitly confirms that the driver implements // VolumeLifecyclePersistent explicitly confirms that the driver implements
// the full CSI spec. It is the default when CSIDriverSpec.VolumeLifecycleModes is not // the full CSI spec. It is the default when CSIDriverSpec.VolumeLifecycleModes is not

View File

@ -54,6 +54,8 @@ var map_CSIDriverSpec = map[string]string{
"volumeLifecycleModes": "VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.", "volumeLifecycleModes": "VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.",
"storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.", "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis is an alpha field and only available when the CSIStorageCapacity feature is enabled. The default is false.",
"fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details. This field is alpha-level, and is only honored by servers that enable the CSIVolumeFSGroupPolicy feature gate.", "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details. This field is alpha-level, and is only honored by servers that enable the CSIVolumeFSGroupPolicy feature gate.",
"tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"<audience>\": {\n \"token\": <token>,\n \"expirationTimestamp\": <expiration timestamp in RFC3339>,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
"requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.\n\nThis is an alpha feature and only available when the CSIServiceAccountToken feature is enabled.",
} }
func (CSIDriverSpec) SwaggerDoc() map[string]string { func (CSIDriverSpec) SwaggerDoc() map[string]string {
@ -127,6 +129,16 @@ func (StorageClassList) SwaggerDoc() map[string]string {
return map_StorageClassList return map_StorageClassList
} }
var map_TokenRequest = map[string]string{
"": "TokenRequest contains parameters of a service account token.",
"audience": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.",
"expirationSeconds": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\"",
}
func (TokenRequest) SwaggerDoc() map[string]string {
return map_TokenRequest
}
var map_VolumeAttachment = map[string]string{ var map_VolumeAttachment = map[string]string{
"": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.",
"metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",

View File

@ -113,6 +113,18 @@ func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) {
*out = new(FSGroupPolicy) *out = new(FSGroupPolicy)
**out = **in **out = **in
} }
if in.TokenRequests != nil {
in, out := &in.TokenRequests, &out.TokenRequests
*out = make([]TokenRequest, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.RequiresRepublish != nil {
in, out := &in.RequiresRepublish, &out.RequiresRepublish
*out = new(bool)
**out = **in
}
return return
} }
@ -328,6 +340,27 @@ func (in *StorageClassList) DeepCopyObject() runtime.Object {
return nil return nil
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenRequest) DeepCopyInto(out *TokenRequest) {
*out = *in
if in.ExpirationSeconds != nil {
in, out := &in.ExpirationSeconds, &out.ExpirationSeconds
*out = new(int64)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenRequest.
func (in *TokenRequest) DeepCopy() *TokenRequest {
if in == nil {
return nil
}
out := new(TokenRequest)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeAttachment) DeepCopyInto(out *VolumeAttachment) { func (in *VolumeAttachment) DeepCopyInto(out *VolumeAttachment) {
*out = *in *out = *in

View File

@ -47,6 +47,13 @@
"r鯹)晿\u003co,c鮽ort昍řČ扷5ƗǸ" "r鯹)晿\u003co,c鮽ort昍řČ扷5ƗǸ"
], ],
"storageCapacity": true, "storageCapacity": true,
"fsGroupPolicy": "/ʕVŚ(ĿȊ甞谐颋DžSǡ" "fsGroupPolicy": "/ʕVŚ(ĿȊ甞谐颋DžSǡ",
"tokenRequests": [
{
"audience": "19",
"expirationSeconds": -8506428344202195448
}
],
"requiresRepublish": false
} }
} }

View File

@ -33,6 +33,10 @@ spec:
attachRequired: false attachRequired: false
fsGroupPolicy: /ʕVŚ(ĿȊ甞谐颋DžSǡ fsGroupPolicy: /ʕVŚ(ĿȊ甞谐颋DžSǡ
podInfoOnMount: false podInfoOnMount: false
requiresRepublish: false
storageCapacity: true storageCapacity: true
tokenRequests:
- audience: "19"
expirationSeconds: -8506428344202195448
volumeLifecycleModes: volumeLifecycleModes:
- r鯹)晿<o,c鮽ort昍řČ扷5ƗǸ - r鯹)晿<o,c鮽ort昍řČ扷5ƗǸ

View File

@ -47,6 +47,13 @@
"r鯹)晿\u003co,c鮽ort昍řČ扷5ƗǸ" "r鯹)晿\u003co,c鮽ort昍řČ扷5ƗǸ"
], ],
"storageCapacity": true, "storageCapacity": true,
"fsGroupPolicy": "/ʕVŚ(ĿȊ甞谐颋DžSǡ" "fsGroupPolicy": "/ʕVŚ(ĿȊ甞谐颋DžSǡ",
"tokenRequests": [
{
"audience": "19",
"expirationSeconds": -8506428344202195448
}
],
"requiresRepublish": false
} }
} }

View File

@ -33,6 +33,10 @@ spec:
attachRequired: false attachRequired: false
fsGroupPolicy: /ʕVŚ(ĿȊ甞谐颋DžSǡ fsGroupPolicy: /ʕVŚ(ĿȊ甞谐颋DžSǡ
podInfoOnMount: false podInfoOnMount: false
requiresRepublish: false
storageCapacity: true storageCapacity: true
tokenRequests:
- audience: "19"
expirationSeconds: -8506428344202195448
volumeLifecycleModes: volumeLifecycleModes:
- r鯹)晿<o,c鮽ort昍řČ扷5ƗǸ - r鯹)晿<o,c鮽ort昍řČ扷5ƗǸ

View File

@ -243,6 +243,7 @@ rules:
- k8s.io/kubernetes/pkg/apis/authentication - k8s.io/kubernetes/pkg/apis/authentication
- k8s.io/kubernetes/pkg/apis/authentication/v1 - k8s.io/kubernetes/pkg/apis/authentication/v1
- k8s.io/kubernetes/pkg/apis/certificates/v1beta1 - k8s.io/kubernetes/pkg/apis/certificates/v1beta1
- k8s.io/kubernetes/pkg/apis/storage/v1
- k8s.io/kubernetes/pkg/scheduler/internal/cache - k8s.io/kubernetes/pkg/scheduler/internal/cache
- selectorRegexp: k8s[.]io/kubernetes/test/ - selectorRegexp: k8s[.]io/kubernetes/test/
allowedPrefixes: allowedPrefixes:

View File

@ -100,6 +100,7 @@ go_library(
"//vendor/github.com/onsi/gomega:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/google.golang.org/api/googleapi:go_default_library", "//vendor/google.golang.org/api/googleapi:go_default_library",
"//vendor/google.golang.org/grpc/codes:go_default_library", "//vendor/google.golang.org/grpc/codes:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library",
], ],
) )

View File

@ -54,6 +54,7 @@ import (
"k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/testsuites"
"k8s.io/kubernetes/test/e2e/storage/utils" "k8s.io/kubernetes/test/e2e/storage/utils"
imageutils "k8s.io/kubernetes/test/utils/image" imageutils "k8s.io/kubernetes/test/utils/image"
utilptr "k8s.io/utils/pointer"
"github.com/onsi/ginkgo" "github.com/onsi/ginkgo"
"github.com/onsi/gomega" "github.com/onsi/gomega"
@ -111,6 +112,8 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
disableResizingOnDriver bool disableResizingOnDriver bool
enableSnapshot bool enableSnapshot bool
javascriptHooks map[string]string javascriptHooks map[string]string
tokenRequests []storagev1.TokenRequest
requiresRepublish *bool
} }
type mockDriverSetup struct { type mockDriverSetup struct {
@ -150,6 +153,8 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
EnableNodeExpansion: tp.enableNodeExpansion, EnableNodeExpansion: tp.enableNodeExpansion,
EnableSnapshot: tp.enableSnapshot, EnableSnapshot: tp.enableSnapshot,
JavascriptHooks: tp.javascriptHooks, JavascriptHooks: tp.javascriptHooks,
TokenRequests: tp.tokenRequests,
RequiresRepublish: tp.requiresRepublish,
} }
// this just disable resizing on driver, keeping resizing on SC enabled. // this just disable resizing on driver, keeping resizing on SC enabled.
@ -471,7 +476,7 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
framework.ExpectNoError(err, "while deleting") framework.ExpectNoError(err, "while deleting")
ginkgo.By("Checking CSI driver logs") ginkgo.By("Checking CSI driver logs")
err = checkPodLogs(m.cs, m.config.DriverNamespace.Name, driverPodName, driverContainerName, pod, test.expectPodInfo, test.expectEphemeral, csiInlineVolumesEnabled) err = checkPodLogs(m.cs, m.config.DriverNamespace.Name, driverPodName, driverContainerName, pod, test.expectPodInfo, test.expectEphemeral, csiInlineVolumesEnabled, false, 1)
framework.ExpectNoError(err) framework.ExpectNoError(err)
}) })
} }
@ -1176,6 +1181,7 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
}) })
} }
}) })
ginkgo.Context("CSI Volume Snapshots [Feature:VolumeSnapshotDataSource]", func() { ginkgo.Context("CSI Volume Snapshots [Feature:VolumeSnapshotDataSource]", func() {
// Global variable in all scripts (called before each test) // Global variable in all scripts (called before each test)
globalScript := `counter=0; console.log("globals loaded", OK, DEADLINEEXCEEDED)` globalScript := `counter=0; console.log("globals loaded", OK, DEADLINEEXCEEDED)`
@ -1301,6 +1307,68 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
}) })
} }
}) })
ginkgo.Context("CSIServiceAccountToken [Feature:CSIServiceAccountToken]", func() {
var (
err error
)
tests := []struct {
desc string
deployCSIDriverObject bool
tokenRequests []storagev1.TokenRequest
}{
{
desc: "token should not be plumbed down when csiServiceAccountTokenEnabled=false",
deployCSIDriverObject: true,
tokenRequests: nil,
},
{
desc: "token should not be plumbed down when CSIDriver is not deployed",
deployCSIDriverObject: false,
tokenRequests: []storagev1.TokenRequest{{}},
},
{
desc: "token should be plumbed down when csiServiceAccountTokenEnabled=true",
deployCSIDriverObject: true,
tokenRequests: []storagev1.TokenRequest{{ExpirationSeconds: utilptr.Int64Ptr(60 * 10)}},
},
}
for _, test := range tests {
test := test
csiServiceAccountTokenEnabled := test.tokenRequests != nil
ginkgo.It(test.desc, func() {
init(testParameters{
registerDriver: test.deployCSIDriverObject,
tokenRequests: test.tokenRequests,
requiresRepublish: &csiServiceAccountTokenEnabled,
})
defer cleanup()
_, _, pod := createPod(false)
if pod == nil {
return
}
err = e2epod.WaitForPodNameRunningInNamespace(m.cs, pod.Name, pod.Namespace)
framework.ExpectNoError(err, "Failed to start pod: %v", err)
// sleep to make sure RequiresRepublish triggers more than 1 NodePublishVolume
numNodePublishVolume := 1
if test.deployCSIDriverObject && csiServiceAccountTokenEnabled {
time.Sleep(time.Second)
numNodePublishVolume = 2
}
ginkgo.By("Deleting the previously created pod")
err = e2epod.DeletePodWithWait(m.cs, pod)
framework.ExpectNoError(err, "while deleting")
ginkgo.By("Checking CSI driver logs")
err = checkPodLogs(m.cs, m.config.DriverNamespace.Name, driverPodName, driverContainerName, pod, false, false, false, test.deployCSIDriverObject && csiServiceAccountTokenEnabled, numNodePublishVolume)
framework.ExpectNoError(err)
})
}
})
}) })
// A lot of this code was copied from e2e/framework. It would be nicer // A lot of this code was copied from e2e/framework. It would be nicer
@ -1545,18 +1613,24 @@ type mockCSICall struct {
// checkPodLogs tests that NodePublish was called with expected volume_context and (for ephemeral inline volumes) // checkPodLogs tests that NodePublish was called with expected volume_context and (for ephemeral inline volumes)
// has the matching NodeUnpublish // has the matching NodeUnpublish
func checkPodLogs(cs clientset.Interface, namespace, driverPodName, driverContainerName string, pod *v1.Pod, expectPodInfo, ephemeralVolume, csiInlineVolumesEnabled bool) error { func checkPodLogs(cs clientset.Interface, namespace, driverPodName, driverContainerName string, pod *v1.Pod, expectPodInfo, ephemeralVolume, csiInlineVolumesEnabled, csiServiceAccountTokenEnabled bool, expectedNumNodePublish int) error {
expectedAttributes := map[string]string{ expectedAttributes := map[string]string{}
"csi.storage.k8s.io/pod.name": pod.Name, if expectPodInfo {
"csi.storage.k8s.io/pod.namespace": pod.Namespace, expectedAttributes["csi.storage.k8s.io/pod.name"] = pod.Name
"csi.storage.k8s.io/pod.uid": string(pod.UID), expectedAttributes["csi.storage.k8s.io/pod.namespace"] = pod.Namespace
"csi.storage.k8s.io/serviceAccount.name": "default", expectedAttributes["csi.storage.k8s.io/pod.uid"] = string(pod.UID)
expectedAttributes["csi.storage.k8s.io/serviceAccount.name"] = "default"
} }
if csiInlineVolumesEnabled { if csiInlineVolumesEnabled {
// This is only passed in 1.15 when the CSIInlineVolume feature gate is set. // This is only passed in 1.15 when the CSIInlineVolume feature gate is set.
expectedAttributes["csi.storage.k8s.io/ephemeral"] = strconv.FormatBool(ephemeralVolume) expectedAttributes["csi.storage.k8s.io/ephemeral"] = strconv.FormatBool(ephemeralVolume)
} }
if csiServiceAccountTokenEnabled {
expectedAttributes["csi.storage.k8s.io/serviceAccount.tokens"] = "<nonempty>"
}
// Find NodePublish in the GRPC calls. // Find NodePublish in the GRPC calls.
foundAttributes := sets.NewString() foundAttributes := sets.NewString()
numNodePublishVolume := 0 numNodePublishVolume := 0
@ -1573,9 +1647,9 @@ func checkPodLogs(cs clientset.Interface, namespace, driverPodName, driverContai
// Check that NodePublish had expected attributes for first volume // Check that NodePublish had expected attributes for first volume
for k, v := range expectedAttributes { for k, v := range expectedAttributes {
vv, found := call.Request.VolumeContext[k] vv, found := call.Request.VolumeContext[k]
if found && v == vv { if found && (v == vv || (v == "<nonempty>" && len(vv) != 0)) {
foundAttributes.Insert(k) foundAttributes.Insert(k)
framework.Logf("Found volume attribute %s: %s", k, v) framework.Logf("Found volume attribute %s: %s", k, vv)
} }
} }
} }
@ -1584,23 +1658,16 @@ func checkPodLogs(cs clientset.Interface, namespace, driverPodName, driverContai
numNodeUnpublishVolume++ numNodeUnpublishVolume++
} }
} }
if numNodePublishVolume == 0 { if numNodePublishVolume < expectedNumNodePublish {
return fmt.Errorf("NodePublish was never called") return fmt.Errorf("NodePublish should be called at least %d", expectedNumNodePublish)
} }
if numNodeUnpublishVolume == 0 { if numNodeUnpublishVolume == 0 {
return fmt.Errorf("NodeUnpublish was never called") return fmt.Errorf("NodeUnpublish was never called")
} }
if expectPodInfo { if foundAttributes.Len() != len(expectedAttributes) {
if foundAttributes.Len() != len(expectedAttributes) { return fmt.Errorf("number of found volume attributes does not match, expected %d, got %d", len(expectedAttributes), foundAttributes.Len())
return fmt.Errorf("number of found volume attributes does not match, expected %d, got %d", len(expectedAttributes), foundAttributes.Len())
}
return nil
} }
if foundAttributes.Len() != 0 {
return fmt.Errorf("some unexpected volume attributes were found: %+v", foundAttributes.List())
}
return nil return nil
} }

View File

@ -253,6 +253,8 @@ type mockCSIDriver struct {
enableNodeExpansion bool enableNodeExpansion bool
cleanupHandle framework.CleanupActionHandle cleanupHandle framework.CleanupActionHandle
javascriptHooks map[string]string javascriptHooks map[string]string
tokenRequests []storagev1.TokenRequest
requiresRepublish *bool
} }
// CSIMockDriverOpts defines options used for csi driver // CSIMockDriverOpts defines options used for csi driver
@ -267,6 +269,8 @@ type CSIMockDriverOpts struct {
EnableNodeExpansion bool EnableNodeExpansion bool
EnableSnapshot bool EnableSnapshot bool
JavascriptHooks map[string]string JavascriptHooks map[string]string
TokenRequests []storagev1.TokenRequest
RequiresRepublish *bool
} }
var _ testsuites.TestDriver = &mockCSIDriver{} var _ testsuites.TestDriver = &mockCSIDriver{}
@ -324,6 +328,8 @@ func InitMockCSIDriver(driverOpts CSIMockDriverOpts) testsuites.TestDriver {
attachLimit: driverOpts.AttachLimit, attachLimit: driverOpts.AttachLimit,
enableNodeExpansion: driverOpts.EnableNodeExpansion, enableNodeExpansion: driverOpts.EnableNodeExpansion,
javascriptHooks: driverOpts.JavascriptHooks, javascriptHooks: driverOpts.JavascriptHooks,
tokenRequests: driverOpts.TokenRequests,
requiresRepublish: driverOpts.RequiresRepublish,
} }
} }
@ -425,6 +431,8 @@ func (m *mockCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTest
storagev1.VolumeLifecyclePersistent, storagev1.VolumeLifecyclePersistent,
storagev1.VolumeLifecycleEphemeral, storagev1.VolumeLifecycleEphemeral,
}, },
TokenRequests: m.tokenRequests,
RequiresRepublish: m.requiresRepublish,
} }
cleanup, err := utils.CreateFromManifests(f, driverNamespace, func(item interface{}) error { cleanup, err := utils.CreateFromManifests(f, driverNamespace, func(item interface{}) error {
return utils.PatchCSIDeployment(f, o, item) return utils.PatchCSIDeployment(f, o, item)

View File

@ -133,6 +133,12 @@ func PatchCSIDeployment(f *framework.Framework, o PatchCSIOptions, object interf
if o.VolumeLifecycleModes != nil { if o.VolumeLifecycleModes != nil {
object.Spec.VolumeLifecycleModes = *o.VolumeLifecycleModes object.Spec.VolumeLifecycleModes = *o.VolumeLifecycleModes
} }
if o.TokenRequests != nil {
object.Spec.TokenRequests = o.TokenRequests
}
if o.RequiresRepublish != nil {
object.Spec.RequiresRepublish = o.RequiresRepublish
}
} }
return nil return nil
@ -180,4 +186,12 @@ type PatchCSIOptions struct {
// field *if* the driver deploys a CSIDriver object. Ignored // field *if* the driver deploys a CSIDriver object. Ignored
// otherwise. // otherwise.
VolumeLifecycleModes *[]storagev1.VolumeLifecycleMode VolumeLifecycleModes *[]storagev1.VolumeLifecycleMode
// If not nil, the value to use for the CSIDriver.Spec.TokenRequests
// field *if* the driver deploys a CSIDriver object. Ignored
// otherwise.
TokenRequests []storagev1.TokenRequest
// If not nil, the value to use for the CSIDriver.Spec.RequiresRepublish
// field *if* the driver deploys a CSIDriver object. Ignored
// otherwise.
RequiresRepublish *bool
} }