mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
csi: add nodeExpandSecret support for CSI client
CSI spec 1.5 enhanced the spec to add optional secrets field to NodeExpandVolumeRequest. This commit adds NodeExpandSecret to the CSI PV source and also derive the expansion secret in csiclient to send it out as part of the nodeexpand request. Signed-off-by: Humble Chirammal <hchiramm@redhat.com> Signed-off-by: zhucan <zhucan.k8s@gmail.com>
This commit is contained in:
parent
eb2ebddf61
commit
c74b393771
44
pkg/api/persistentvolume/util.go
Normal file
44
pkg/api/persistentvolume/util.go
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package persistentvolume
|
||||
|
||||
import (
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// DropDisabledFields removes disabled fields from the pv spec.
|
||||
// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a pv spec.
|
||||
func DropDisabledFields(pvSpec *api.PersistentVolumeSpec, oldPVSpec *api.PersistentVolumeSpec) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSINodeExpandSecret) && !hasNodeExpansionSecrets(oldPVSpec) {
|
||||
if pvSpec.CSI != nil {
|
||||
pvSpec.CSI.NodeExpandSecretRef = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func hasNodeExpansionSecrets(oldPVSpec *api.PersistentVolumeSpec) bool {
|
||||
if oldPVSpec == nil || oldPVSpec.CSI == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if oldPVSpec.CSI.NodeExpandSecretRef != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
@ -147,6 +147,11 @@ func VisitPVSecretNames(pv *corev1.PersistentVolume, visitor Visitor) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if source.CSI.NodeExpandSecretRef != nil {
|
||||
if !visitor(source.CSI.NodeExpandSecretRef.Namespace, source.CSI.NodeExpandSecretRef.Name, true /* kubeletVisible */) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -1716,11 +1716,20 @@ type CSIPersistentVolumeSource struct {
|
||||
// ControllerExpandSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// ControllerExpandVolume call.
|
||||
// This is an alpha field and requires enabling ExpandCSIVolumes feature gate.
|
||||
// This is an beta field and requires enabling ExpandCSIVolumes feature gate.
|
||||
// This field is optional, and may be empty if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
ControllerExpandSecretRef *SecretReference
|
||||
|
||||
// NodeExpandSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// NodeExpandVolume call.
|
||||
// This is an alpha field and requires enabling CSINodeExpandSecret feature gate.
|
||||
// This field is optional, may be omitted if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
NodeExpandSecretRef *SecretReference
|
||||
}
|
||||
|
||||
// CSIVolumeSource represents a source location of a volume to mount, managed by an external CSI driver
|
||||
|
@ -1595,6 +1595,18 @@ func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, fldP
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodePublishSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
}
|
||||
if csi.NodeExpandSecretRef != nil {
|
||||
if len(csi.NodeExpandSecretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodeExpandSecretRef", "name"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Subdomain(csi.NodeExpandSecretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
if len(csi.NodeExpandSecretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodeExpandSecretRef", "namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodeExpandSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
@ -882,6 +882,13 @@ const (
|
||||
//
|
||||
// Enables support for time zones in CronJobs.
|
||||
CronJobTimeZone featuregate.Feature = "CronJobTimeZone"
|
||||
|
||||
// owner: @humblec, @zhucan
|
||||
// kep: http://kep.k8s.io/3171
|
||||
// alpha: v1.24
|
||||
//
|
||||
// Enables SecretRef field in CSI NodeExpandVolume request.
|
||||
CSINodeExpandSecret featuregate.Feature = "CSINodeExpandSecret"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -990,6 +997,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
ReadWriteOncePod: {Default: false, PreRelease: featuregate.Alpha},
|
||||
CSRDuration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
|
||||
DelegateFSGroupToCSIDriver: {Default: true, PreRelease: featuregate.Beta},
|
||||
CSINodeExpandSecret: {Default: false, PreRelease: featuregate.Alpha},
|
||||
KubeletInUserNamespace: {Default: false, PreRelease: featuregate.Alpha},
|
||||
MemoryQoS: {Default: false, PreRelease: featuregate.Alpha},
|
||||
CPUManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
pvutil "k8s.io/kubernetes/pkg/api/persistentvolume"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
volumevalidation "k8s.io/kubernetes/pkg/volume/validation"
|
||||
@ -62,6 +63,10 @@ func (persistentvolumeStrategy) GetResetFields() map[fieldpath.APIVersion]*field
|
||||
|
||||
// ResetBeforeCreate clears the Status field which is not allowed to be set by end users on creation.
|
||||
func (persistentvolumeStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
|
||||
pv := obj.(*api.PersistentVolume)
|
||||
pv.Status = api.PersistentVolumeStatus{}
|
||||
|
||||
pvutil.DropDisabledFields(&pv.Spec, nil)
|
||||
}
|
||||
|
||||
func (persistentvolumeStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||
@ -89,6 +94,8 @@ func (persistentvolumeStrategy) PrepareForUpdate(ctx context.Context, obj, old r
|
||||
newPv := obj.(*api.PersistentVolume)
|
||||
oldPv := old.(*api.PersistentVolume)
|
||||
newPv.Status = oldPv.Status
|
||||
|
||||
pvutil.DropDisabledFields(&newPv.Spec, &oldPv.Spec)
|
||||
}
|
||||
|
||||
func (persistentvolumeStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||
|
@ -120,6 +120,7 @@ type csiResizeOptions struct {
|
||||
accessMode api.PersistentVolumeAccessMode
|
||||
newSize resource.Quantity
|
||||
mountOptions []string
|
||||
secrets map[string]string
|
||||
}
|
||||
|
||||
var _ csiClient = &csiDriverClient{}
|
||||
@ -320,6 +321,7 @@ func (c *csiDriverClient) NodeExpandVolume(ctx context.Context, opts csiResizeOp
|
||||
Mode: accessModeMapper(opts.accessMode),
|
||||
},
|
||||
},
|
||||
Secrets: opts.secrets,
|
||||
}
|
||||
|
||||
// not all CSI drivers support NodeStageUnstage and hence the StagingTargetPath
|
||||
|
@ -23,7 +23,9 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
api "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
|
||||
@ -77,6 +79,17 @@ func (c *csiPlugin) nodeExpandWithClient(
|
||||
if pv == nil {
|
||||
return false, fmt.Errorf("Expander.NodeExpand failed to find associated PersistentVolume for plugin %s", c.GetPluginName())
|
||||
}
|
||||
nodeExpandSecrets := map[string]string{}
|
||||
expandClient := c.host.GetKubeClient()
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.CSINodeExpandSecret) {
|
||||
if csiSource.NodeExpandSecretRef != nil {
|
||||
nodeExpandSecrets, err = getCredentialsFromSecret(expandClient, csiSource.NodeExpandSecretRef)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("expander.NodeExpand failed to get NodeExpandSecretRef %s/%s: %v",
|
||||
csiSource.NodeExpandSecretRef.Namespace, csiSource.NodeExpandSecretRef.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opts := csiResizeOptions{
|
||||
volumePath: resizeOptions.DeviceMountPath,
|
||||
@ -86,6 +99,7 @@ func (c *csiPlugin) nodeExpandWithClient(
|
||||
fsType: csiSource.FSType,
|
||||
accessMode: api.ReadWriteOnce,
|
||||
mountOptions: pv.Spec.MountOptions,
|
||||
secrets: nodeExpandSecrets,
|
||||
}
|
||||
|
||||
if !fsVolume {
|
||||
|
@ -1800,11 +1800,20 @@ type CSIPersistentVolumeSource struct {
|
||||
// controllerExpandSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// ControllerExpandVolume call.
|
||||
// This is an alpha field and requires enabling ExpandCSIVolumes feature gate.
|
||||
// This is an beta field and requires enabling ExpandCSIVolumes feature gate.
|
||||
// This field is optional, and may be empty if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
ControllerExpandSecretRef *SecretReference `json:"controllerExpandSecretRef,omitempty" protobuf:"bytes,9,opt,name=controllerExpandSecretRef"`
|
||||
|
||||
// nodeExpandSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// NodeExpandVolume call.
|
||||
// This is an alpha field and requires enabling CSINodeExpandSecret feature gate.
|
||||
// This field is optional, may be omitted if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
NodeExpandSecretRef *SecretReference `json:"nodeExpandSecretRef,omitempty" protobuf:"bytes,10,opt,name=nodeExpandSecretRef"`
|
||||
}
|
||||
|
||||
// Represents a source location of a volume to mount, managed by an external CSI driver
|
||||
|
Loading…
Reference in New Issue
Block a user