Merge pull request #47660 from rootfs/azure-file-ns

Automatic merge from submit-queue (batch tested with PRs 50713, 47660, 51198, 51159, 51195)

add secret namespace to azure file 

**What this PR does / why we need it**:
allow provisioner to create stoarge account secret in different namespace
**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #47452 

**Special notes for your reviewer**:
@liggitt @brendandburns 

**Release note**:

```release-note
Azure file persistent volumes can use a new `secretNamespace` field to reference a secret in a different namespace than the one containing their bound persistent volume claim. The azure file persistent volume provisioner honors a corresponding `secretNamespace` storage class parameter to determine where to place secrets containing the storage account key.
```
This commit is contained in:
Kubernetes Submit Queue 2017-08-24 11:17:05 -07:00 committed by GitHub
commit b527ba2ec7
20 changed files with 1969 additions and 962 deletions

View File

@ -58134,6 +58134,31 @@
}
}
},
"io.k8s.api.core.v1.AzureFilePersistentVolumeSource": {
"description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"required": [
"secretName",
"shareName"
],
"properties": {
"readOnly": {
"description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.",
"type": "boolean"
},
"secretName": {
"description": "the name of secret that contains Azure Storage Account Name and Key",
"type": "string"
},
"secretNamespace": {
"description": "the namespace of the secret that contains Azure Storage Account Name and Key default is the same as the Pod",
"type": "string"
},
"shareName": {
"description": "Share Name",
"type": "string"
}
}
},
"io.k8s.api.core.v1.AzureFileVolumeSource": {
"description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"required": [
@ -60429,7 +60454,7 @@
},
"azureFile": {
"description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"$ref": "#/definitions/io.k8s.api.core.v1.AzureFileVolumeSource"
"$ref": "#/definitions/io.k8s.api.core.v1.AzureFilePersistentVolumeSource"
},
"capacity": {
"description": "A description of the persistent volume's resources and capacity. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#capacity",

View File

@ -18881,7 +18881,7 @@
"description": "FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. This is an alpha feature and may change in future."
},
"azureFile": {
"$ref": "v1.AzureFileVolumeSource",
"$ref": "v1.AzureFilePersistentVolumeSource",
"description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod."
},
"vsphereVolume": {
@ -19301,12 +19301,13 @@
}
}
},
"v1.AzureFileVolumeSource": {
"id": "v1.AzureFileVolumeSource",
"v1.AzureFilePersistentVolumeSource": {
"id": "v1.AzureFilePersistentVolumeSource",
"description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"required": [
"secretName",
"shareName"
"shareName",
"secretNamespace"
],
"properties": {
"secretName": {
@ -19320,6 +19321,10 @@
"readOnly": {
"type": "boolean",
"description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
},
"secretNamespace": {
"type": "string",
"description": "the namespace of the secret that contains Azure Storage Account Name and Key default is the same as the Pod"
}
}
},
@ -20054,6 +20059,28 @@
}
}
},
"v1.AzureFileVolumeSource": {
"id": "v1.AzureFileVolumeSource",
"description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"required": [
"secretName",
"shareName"
],
"properties": {
"secretName": {
"type": "string",
"description": "the name of secret that contains Azure Storage Account Name and Key"
},
"shareName": {
"type": "string",
"description": "Share Name"
},
"readOnly": {
"type": "boolean",
"description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
}
}
},
"v1.ConfigMapVolumeSource": {
"id": "v1.ConfigMapVolumeSource",
"description": "Adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. ConfigMap volumes support ownership management and SELinux relabeling.",

View File

@ -2567,10 +2567,6 @@ When an object is created, the system will populate this list with the current s
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_types_uid">types.UID</h3>
</div>
<div class="sect2">
<h3 id="_v1_azurefilevolumesource">v1.AzureFileVolumeSource</h3>
@ -2619,6 +2615,10 @@ When an object is created, the system will populate this list with the current s
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_types_uid">types.UID</h3>
</div>
<div class="sect2">
<h3 id="_v1_iscsivolumesource">v1.ISCSIVolumeSource</h3>
@ -7447,7 +7447,7 @@ Examples:<br>
<td class="tableblock halign-left valign-top"><p class="tableblock">azureFile</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">AzureFile represents an Azure File Service mount on the host and bind mount to the pod.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_azurefilevolumesource">v1.AzureFileVolumeSource</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_azurefilepersistentvolumesource">v1.AzureFilePersistentVolumeSource</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
@ -10117,6 +10117,61 @@ Examples:<br>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_azurefilepersistentvolumesource">v1.AzureFilePersistentVolumeSource</h3>
<div class="paragraph">
<p>AzureFile represents an Azure File Service mount on the host and bind mount to the pod.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">secretName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">the name of secret that contains Azure Storage Account Name and Key</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">shareName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Share Name</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">readOnly</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">secretNamespace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">the namespace of the secret that contains Azure Storage Account Name and Key default is the same as the Pod</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_pod">v1.Pod</h3>

View File

@ -37,8 +37,14 @@ func VisitPVSecretNames(pv *api.PersistentVolume, visitor Visitor) bool {
source := &pv.Spec.PersistentVolumeSource
switch {
case source.AzureFile != nil:
if len(source.AzureFile.SecretName) > 0 && !visitor(getClaimRefNamespace(pv), source.AzureFile.SecretName) {
return false
if source.AzureFile.SecretNamespace != nil && len(*source.AzureFile.SecretNamespace) > 0 {
if len(source.AzureFile.SecretName) > 0 && !visitor(*source.AzureFile.SecretNamespace, source.AzureFile.SecretName) {
return false
}
} else {
if len(source.AzureFile.SecretName) > 0 && !visitor(getClaimRefNamespace(pv), source.AzureFile.SecretName) {
return false
}
}
return true
case source.CephFS != nil:

View File

@ -30,12 +30,19 @@ import (
func TestPVSecrets(t *testing.T) {
// Stub containing all possible secret references in a PV.
// The names of the referenced secrets match struct paths detected by reflection.
secretNamespace := "Spec.PersistentVolumeSource.AzureFile.SecretNamespace"
pvs := []*api.PersistentVolume{
{Spec: api.PersistentVolumeSpec{
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
PersistentVolumeSource: api.PersistentVolumeSource{
AzureFile: &api.AzureFileVolumeSource{
AzureFile: &api.AzureFilePersistentVolumeSource{
SecretName: "Spec.PersistentVolumeSource.AzureFile.SecretName"}}}},
{Spec: api.PersistentVolumeSpec{
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
PersistentVolumeSource: api.PersistentVolumeSource{
AzureFile: &api.AzureFilePersistentVolumeSource{
SecretName: "Spec.PersistentVolumeSource.AzureFile.SecretName",
SecretNamespace: &secretNamespace}}}},
{Spec: api.PersistentVolumeSpec{
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
PersistentVolumeSource: api.PersistentVolumeSource{
@ -88,6 +95,7 @@ func TestPVSecrets(t *testing.T) {
// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
excludedSecretPaths := sets.NewString(
"Spec.PersistentVolumeSource.CephFS.SecretFile",
"Spec.PersistentVolumeSource.AzureFile.SecretNamespace",
)
// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
// every path here should be represented as an example in the PV stub above, with the secret name set to the path.
@ -122,6 +130,7 @@ func TestPVSecrets(t *testing.T) {
expectedNamespacedNames := sets.NewString(
"claimrefns/Spec.PersistentVolumeSource.AzureFile.SecretName",
"Spec.PersistentVolumeSource.AzureFile.SecretNamespace/Spec.PersistentVolumeSource.AzureFile.SecretName",
"claimrefns/Spec.PersistentVolumeSource.CephFS.SecretRef",
"claimrefns/Spec.PersistentVolumeSource.FlexVolume.SecretRef",
"claimrefns/Spec.PersistentVolumeSource.RBD.SecretRef",

View File

@ -369,7 +369,7 @@ type PersistentVolumeSource struct {
Flocker *FlockerVolumeSource
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
// +optional
AzureFile *AzureFileVolumeSource
AzureFile *AzureFilePersistentVolumeSource
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
// +optional
VsphereVolume *VsphereVirtualDiskVolumeSource
@ -1087,6 +1087,22 @@ type AzureFileVolumeSource struct {
ReadOnly bool
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
type AzureFilePersistentVolumeSource struct {
// the name of secret that contains Azure Storage Account Name and Key
SecretName string
// Share Name
ShareName string
// Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
// +optional
ReadOnly bool
// the namespace of the secret that contains Azure Storage Account Name and Key
// default is the same as the Pod
// +optional
SecretNamespace *string
}
// Represents a vSphere volume resource.
type VsphereVirtualDiskVolumeSource struct {
// Path that identifies vSphere volume vmdk

View File

@ -48,6 +48,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_api_AvoidPods_To_v1_AvoidPods,
Convert_v1_AzureDiskVolumeSource_To_api_AzureDiskVolumeSource,
Convert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource,
Convert_v1_AzureFilePersistentVolumeSource_To_api_AzureFilePersistentVolumeSource,
Convert_api_AzureFilePersistentVolumeSource_To_v1_AzureFilePersistentVolumeSource,
Convert_v1_AzureFileVolumeSource_To_api_AzureFileVolumeSource,
Convert_api_AzureFileVolumeSource_To_v1_AzureFileVolumeSource,
Convert_v1_Binding_To_api_Binding,
@ -507,6 +509,32 @@ func Convert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource(in *api.Azure
return autoConvert_api_AzureDiskVolumeSource_To_v1_AzureDiskVolumeSource(in, out, s)
}
func autoConvert_v1_AzureFilePersistentVolumeSource_To_api_AzureFilePersistentVolumeSource(in *v1.AzureFilePersistentVolumeSource, out *api.AzureFilePersistentVolumeSource, s conversion.Scope) error {
out.SecretName = in.SecretName
out.ShareName = in.ShareName
out.ReadOnly = in.ReadOnly
out.SecretNamespace = (*string)(unsafe.Pointer(in.SecretNamespace))
return nil
}
// Convert_v1_AzureFilePersistentVolumeSource_To_api_AzureFilePersistentVolumeSource is an autogenerated conversion function.
func Convert_v1_AzureFilePersistentVolumeSource_To_api_AzureFilePersistentVolumeSource(in *v1.AzureFilePersistentVolumeSource, out *api.AzureFilePersistentVolumeSource, s conversion.Scope) error {
return autoConvert_v1_AzureFilePersistentVolumeSource_To_api_AzureFilePersistentVolumeSource(in, out, s)
}
func autoConvert_api_AzureFilePersistentVolumeSource_To_v1_AzureFilePersistentVolumeSource(in *api.AzureFilePersistentVolumeSource, out *v1.AzureFilePersistentVolumeSource, s conversion.Scope) error {
out.SecretName = in.SecretName
out.ShareName = in.ShareName
out.ReadOnly = in.ReadOnly
out.SecretNamespace = (*string)(unsafe.Pointer(in.SecretNamespace))
return nil
}
// Convert_api_AzureFilePersistentVolumeSource_To_v1_AzureFilePersistentVolumeSource is an autogenerated conversion function.
func Convert_api_AzureFilePersistentVolumeSource_To_v1_AzureFilePersistentVolumeSource(in *api.AzureFilePersistentVolumeSource, out *v1.AzureFilePersistentVolumeSource, s conversion.Scope) error {
return autoConvert_api_AzureFilePersistentVolumeSource_To_v1_AzureFilePersistentVolumeSource(in, out, s)
}
func autoConvert_v1_AzureFileVolumeSource_To_api_AzureFileVolumeSource(in *v1.AzureFileVolumeSource, out *api.AzureFileVolumeSource, s conversion.Scope) error {
out.SecretName = in.SecretName
out.ShareName = in.ShareName
@ -3066,7 +3094,7 @@ func autoConvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *v1.
out.FC = (*api.FCVolumeSource)(unsafe.Pointer(in.FC))
out.Flocker = (*api.FlockerVolumeSource)(unsafe.Pointer(in.Flocker))
out.FlexVolume = (*api.FlexVolumeSource)(unsafe.Pointer(in.FlexVolume))
out.AzureFile = (*api.AzureFileVolumeSource)(unsafe.Pointer(in.AzureFile))
out.AzureFile = (*api.AzureFilePersistentVolumeSource)(unsafe.Pointer(in.AzureFile))
out.VsphereVolume = (*api.VsphereVirtualDiskVolumeSource)(unsafe.Pointer(in.VsphereVolume))
out.Quobyte = (*api.QuobyteVolumeSource)(unsafe.Pointer(in.Quobyte))
out.AzureDisk = (*api.AzureDiskVolumeSource)(unsafe.Pointer(in.AzureDisk))
@ -3097,7 +3125,7 @@ func autoConvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api
out.CephFS = (*v1.CephFSVolumeSource)(unsafe.Pointer(in.CephFS))
out.FC = (*v1.FCVolumeSource)(unsafe.Pointer(in.FC))
out.Flocker = (*v1.FlockerVolumeSource)(unsafe.Pointer(in.Flocker))
out.AzureFile = (*v1.AzureFileVolumeSource)(unsafe.Pointer(in.AzureFile))
out.AzureFile = (*v1.AzureFilePersistentVolumeSource)(unsafe.Pointer(in.AzureFile))
out.VsphereVolume = (*v1.VsphereVirtualDiskVolumeSource)(unsafe.Pointer(in.VsphereVolume))
out.AzureDisk = (*v1.AzureDiskVolumeSource)(unsafe.Pointer(in.AzureDisk))
out.PhotonPersistentDisk = (*v1.PhotonPersistentDiskVolumeSource)(unsafe.Pointer(in.PhotonPersistentDisk))

View File

@ -1098,6 +1098,22 @@ func validateAzureFile(azure *api.AzureFileVolumeSource, fldPath *field.Path) fi
return allErrs
}
func validateAzureFilePV(azure *api.AzureFilePersistentVolumeSource, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if azure.SecretName == "" {
allErrs = append(allErrs, field.Required(fldPath.Child("secretName"), ""))
}
if azure.ShareName == "" {
allErrs = append(allErrs, field.Required(fldPath.Child("shareName"), ""))
}
if azure.SecretNamespace != nil {
if len(*azure.SecretNamespace) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("secretNamespace"), ""))
}
}
return allErrs
}
func validateAzureDisk(azure *api.AzureDiskVolumeSource, fldPath *field.Path) field.ErrorList {
var supportedCachingModes = sets.NewString(string(api.AzureDataDiskCachingNone), string(api.AzureDataDiskCachingReadOnly), string(api.AzureDataDiskCachingReadWrite))
var supportedDiskKinds = sets.NewString(string(api.AzureSharedBlobDisk), string(api.AzureDedicatedBlobDisk), string(api.AzureManagedDisk))
@ -1375,7 +1391,7 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
} else {
numVolumes++
allErrs = append(allErrs, validateAzureFile(pv.Spec.AzureFile, specPath.Child("azureFile"))...)
allErrs = append(allErrs, validateAzureFilePV(pv.Spec.AzureFile, specPath.Child("azureFile"))...)
}
}

View File

@ -58,6 +58,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
in.(*AzureDiskVolumeSource).DeepCopyInto(out.(*AzureDiskVolumeSource))
return nil
}, InType: reflect.TypeOf(&AzureDiskVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*AzureFilePersistentVolumeSource).DeepCopyInto(out.(*AzureFilePersistentVolumeSource))
return nil
}, InType: reflect.TypeOf(&AzureFilePersistentVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*AzureFileVolumeSource).DeepCopyInto(out.(*AzureFileVolumeSource))
return nil
@ -879,6 +883,31 @@ func (in *AzureDiskVolumeSource) DeepCopy() *AzureDiskVolumeSource {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureFilePersistentVolumeSource) DeepCopyInto(out *AzureFilePersistentVolumeSource) {
*out = *in
if in.SecretNamespace != nil {
in, out := &in.SecretNamespace, &out.SecretNamespace
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureFilePersistentVolumeSource.
func (in *AzureFilePersistentVolumeSource) DeepCopy() *AzureFilePersistentVolumeSource {
if in == nil {
return nil
}
out := new(AzureFilePersistentVolumeSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureFileVolumeSource) DeepCopyInto(out *AzureFileVolumeSource) {
*out = *in
@ -3679,8 +3708,8 @@ func (in *PersistentVolumeSource) DeepCopyInto(out *PersistentVolumeSource) {
if *in == nil {
*out = nil
} else {
*out = new(AzureFileVolumeSource)
**out = **in
*out = new(AzureFilePersistentVolumeSource)
(*in).DeepCopyInto(*out)
}
}
if in.VsphereVolume != nil {

View File

@ -993,6 +993,19 @@ func printAzureFileVolumeSource(azureFile *api.AzureFileVolumeSource, w PrefixWr
azureFile.SecretName, azureFile.ShareName, azureFile.ReadOnly)
}
func printAzureFilePersistentVolumeSource(azureFile *api.AzureFilePersistentVolumeSource, w PrefixWriter) {
ns := ""
if azureFile.SecretNamespace != nil {
ns = *azureFile.SecretNamespace
}
w.Write(LEVEL_2, "Type:\tAzureFile (an Azure File Service mount on the host and bind mount to the pod)\n"+
" SecretName:\t%v\n"+
" SecretNamespace:\t%v\n"+
" ShareName:\t%v\n"+
" ReadOnly:\t%v\n",
azureFile.SecretName, ns, azureFile.ShareName, azureFile.ReadOnly)
}
func printFlexVolumeSource(flex *api.FlexVolumeSource, w PrefixWriter) {
w.Write(LEVEL_2, "Type:\tFlexVolume (a generic volume resource that is provisioned/attached using an exec based plugin)\n"+
" Driver:\t%v\n"+
@ -1088,7 +1101,7 @@ func describePersistentVolume(pv *api.PersistentVolume, events *api.EventList) (
case pv.Spec.FC != nil:
printFCVolumeSource(pv.Spec.FC, w)
case pv.Spec.AzureFile != nil:
printAzureFileVolumeSource(pv.Spec.AzureFile, w)
printAzureFilePersistentVolumeSource(pv.Spec.AzureFile, w)
case pv.Spec.FlexVolume != nil:
printFlexVolumeSource(pv.Spec.FlexVolume, w)
case pv.Spec.Flocker != nil:

View File

@ -63,12 +63,12 @@ func (plugin *azureFilePlugin) GetPluginName() string {
}
func (plugin *azureFilePlugin) GetVolumeName(spec *volume.Spec) (string, error) {
volumeSource, _, err := getVolumeSource(spec)
share, _, err := getVolumeSource(spec)
if err != nil {
return "", err
}
return volumeSource.ShareName, nil
return share, nil
}
func (plugin *azureFilePlugin) CanSupport(spec *volume.Spec) bool {
@ -102,11 +102,11 @@ func (plugin *azureFilePlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volu
}
func (plugin *azureFilePlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, util azureUtil, mounter mount.Interface) (volume.Mounter, error) {
source, readOnly, err := getVolumeSource(spec)
share, readOnly, err := getVolumeSource(spec)
if err != nil {
return nil, err
}
secretName, secretNamespace, err := getSecretNameAndNamespace(spec, pod.Namespace)
return &azureFileMounter{
azureFile: &azureFile{
volName: spec.Name(),
@ -115,11 +115,12 @@ func (plugin *azureFilePlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod
plugin: plugin,
MetricsProvider: volume.NewMetricsStatFS(getPath(pod.UID, spec.Name(), plugin.host)),
},
util: util,
secretName: source.SecretName,
shareName: source.ShareName,
readOnly: readOnly,
mountOptions: volume.MountOptionFromSpec(spec),
util: util,
secretNamespace: secretNamespace,
secretName: secretName,
shareName: share,
readOnly: readOnly,
mountOptions: volume.MountOptionFromSpec(spec),
}, nil
}
@ -166,11 +167,12 @@ func (azureFileVolume *azureFile) GetPath() string {
type azureFileMounter struct {
*azureFile
util azureUtil
secretName string
shareName string
readOnly bool
mountOptions []string
util azureUtil
secretName string
secretNamespace string
shareName string
readOnly bool
mountOptions []string
}
var _ volume.Mounter = &azureFileMounter{}
@ -205,7 +207,7 @@ func (b *azureFileMounter) SetUpAt(dir string, fsGroup *int64) error {
return nil
}
var accountKey, accountName string
if accountName, accountKey, err = b.util.GetAzureCredentials(b.plugin.host, b.pod.Namespace, b.secretName); err != nil {
if accountName, accountKey, err = b.util.GetAzureCredentials(b.plugin.host, b.secretNamespace, b.secretName); err != nil {
return err
}
os.MkdirAll(dir, 0700)
@ -260,16 +262,43 @@ func (c *azureFileUnmounter) TearDownAt(dir string) error {
return util.UnmountPath(dir, c.mounter)
}
func getVolumeSource(
spec *volume.Spec) (*v1.AzureFileVolumeSource, bool, error) {
func getVolumeSource(spec *volume.Spec) (string, bool, error) {
if spec.Volume != nil && spec.Volume.AzureFile != nil {
return spec.Volume.AzureFile, spec.Volume.AzureFile.ReadOnly, nil
share := spec.Volume.AzureFile.ShareName
readOnly := spec.Volume.AzureFile.ReadOnly
return share, readOnly, nil
} else if spec.PersistentVolume != nil &&
spec.PersistentVolume.Spec.AzureFile != nil {
return spec.PersistentVolume.Spec.AzureFile, spec.ReadOnly, nil
share := spec.PersistentVolume.Spec.AzureFile.ShareName
readOnly := spec.ReadOnly
return share, readOnly, nil
}
return "", false, fmt.Errorf("Spec does not reference an AzureFile volume type")
}
func getSecretNameAndNamespace(spec *volume.Spec, defaultNamespace string) (string, string, error) {
secretName := ""
secretNamespace := ""
if spec.Volume != nil && spec.Volume.AzureFile != nil {
secretName = spec.Volume.AzureFile.SecretName
secretNamespace = defaultNamespace
} else if spec.PersistentVolume != nil &&
spec.PersistentVolume.Spec.AzureFile != nil {
secretNamespace = defaultNamespace
if spec.PersistentVolume.Spec.AzureFile.SecretNamespace != nil {
secretNamespace = *spec.PersistentVolume.Spec.AzureFile.SecretNamespace
}
secretName = spec.PersistentVolume.Spec.AzureFile.SecretName
} else {
return "", "", fmt.Errorf("Spec does not reference an AzureFile volume type")
}
return nil, false, fmt.Errorf("Spec does not reference an AzureFile volume type")
if len(secretNamespace) == 0 {
return "", "", fmt.Errorf("invalid Azure volume: nil namespace")
}
return secretName, secretNamespace, nil
}
func getAzureCloud(cloudProvider cloudprovider.Interface) (*azure.Cloud, error) {

View File

@ -53,7 +53,7 @@ func TestCanSupport(t *testing.T) {
if !plug.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{AzureFile: &v1.AzureFileVolumeSource{}}}}) {
t.Errorf("Expected true")
}
if !plug.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{AzureFile: &v1.AzureFileVolumeSource{}}}}}) {
if !plug.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{AzureFile: &v1.AzureFilePersistentVolumeSource{}}}}}) {
t.Errorf("Expected true")
}
}
@ -204,7 +204,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
},
Spec: v1.PersistentVolumeSpec{
PersistentVolumeSource: v1.PersistentVolumeSource{
AzureFile: &v1.AzureFileVolumeSource{},
AzureFile: &v1.AzureFilePersistentVolumeSource{},
},
ClaimRef: &v1.ObjectReference{
Name: "claimA",
@ -287,3 +287,83 @@ func TestMounterAndUnmounterTypeAssert(t *testing.T) {
t.Errorf("Volume Unmounter can be type-assert to Mounter")
}
}
type testcase struct {
name string
defaultNs string
spec *volume.Spec
// Expected return of the test
expectedName string
expectedNs string
expectedError error
}
func TestGetSecretNameAndNamespaceForPV(t *testing.T) {
secretNs := "ns"
tests := []testcase{
{
name: "persistent volume source",
defaultNs: "default",
spec: &volume.Spec{
PersistentVolume: &v1.PersistentVolume{
Spec: v1.PersistentVolumeSpec{
PersistentVolumeSource: v1.PersistentVolumeSource{
AzureFile: &v1.AzureFilePersistentVolumeSource{
ShareName: "share",
SecretName: "name",
SecretNamespace: &secretNs,
},
},
},
},
},
expectedName: "name",
expectedNs: "ns",
expectedError: nil,
},
{
name: "persistent volume source without namespace",
defaultNs: "default",
spec: &volume.Spec{
PersistentVolume: &v1.PersistentVolume{
Spec: v1.PersistentVolumeSpec{
PersistentVolumeSource: v1.PersistentVolumeSource{
AzureFile: &v1.AzureFilePersistentVolumeSource{
ShareName: "share",
SecretName: "name",
},
},
},
},
},
expectedName: "name",
expectedNs: "default",
expectedError: nil,
},
{
name: "pod volume source",
defaultNs: "default",
spec: &volume.Spec{
Volume: &v1.Volume{
VolumeSource: v1.VolumeSource{
AzureFile: &v1.AzureFileVolumeSource{
ShareName: "share",
SecretName: "name",
},
},
},
},
expectedName: "name",
expectedNs: "default",
expectedError: nil,
},
}
for _, testcase := range tests {
resultName, resultNs, err := getSecretNameAndNamespace(testcase.spec, testcase.defaultNs)
if err != testcase.expectedError || resultName != testcase.expectedName || resultNs != testcase.expectedNs {
t.Errorf("%s failed: expected err=%v ns=%q name=%q, got %v/%q/%q", testcase.name, testcase.expectedError, testcase.expectedNs, testcase.expectedName,
err, resultNs, resultName)
}
}
}

View File

@ -63,15 +63,13 @@ func (plugin *azureFilePlugin) newDeleterInternal(spec *volume.Spec, util azureU
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.AzureFile == nil {
return nil, fmt.Errorf("invalid PV spec")
}
pvSpec := spec.PersistentVolume
if pvSpec.Spec.ClaimRef.Namespace == "" {
glog.Errorf("namespace cannot be nil")
return nil, fmt.Errorf("invalid PV spec: nil namespace")
secretName, secretNamespace, err := getSecretNameAndNamespace(spec, spec.PersistentVolume.Spec.ClaimRef.Namespace)
if err != nil {
return nil, err
}
nameSpace := pvSpec.Spec.ClaimRef.Namespace
secretName := pvSpec.Spec.AzureFile.SecretName
shareName := pvSpec.Spec.AzureFile.ShareName
if accountName, accountKey, err := util.GetAzureCredentials(plugin.host, nameSpace, secretName); err != nil {
shareName := spec.PersistentVolume.Spec.AzureFile.ShareName
if accountName, accountKey, err := util.GetAzureCredentials(plugin.host, secretNamespace, secretName); err != nil {
return nil, err
} else {
return &azureFileDeleter{
@ -144,7 +142,7 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
capacity := a.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
requestBytes := capacity.Value()
requestGB := int(volume.RoundUpSize(requestBytes, 1024*1024*1024))
secretNamespace := a.options.PVC.Namespace
// Apply ProvisionerParameters (case-insensitive). We leave validation of
// the values to the cloud provider.
for k, v := range a.options.Parameters {
@ -155,6 +153,8 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
location = v
case "storageaccount":
account = v
case "secretnamespace":
secretNamespace = v
default:
return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, a.plugin.GetPluginName())
}
@ -168,8 +168,9 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
if err != nil {
return nil, err
}
// create a secret for storage account and key
secretName, err := a.util.SetAzureCredentials(a.plugin.host, a.options.PVC.Namespace, account, key)
secretName, err := a.util.SetAzureCredentials(a.plugin.host, secretNamespace, account, key)
if err != nil {
return nil, err
}
@ -189,9 +190,10 @@ func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", requestGB)),
},
PersistentVolumeSource: v1.PersistentVolumeSource{
AzureFile: &v1.AzureFileVolumeSource{
SecretName: secretName,
ShareName: name,
AzureFile: &v1.AzureFilePersistentVolumeSource{
SecretName: secretName,
ShareName: name,
SecretNamespace: &secretNamespace,
},
},
},

File diff suppressed because it is too large Load Diff

View File

@ -124,6 +124,25 @@ message AzureDiskVolumeSource {
optional string kind = 6;
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
message AzureFilePersistentVolumeSource {
// the name of secret that contains Azure Storage Account Name and Key
optional string secretName = 1;
// Share Name
optional string shareName = 2;
// Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
// +optional
optional bool readOnly = 3;
// the namespace of the secret that contains Azure Storage Account Name and Key
// default is the same as the Pod
// +optional
optional string secretNamespace = 4;
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
message AzureFileVolumeSource {
// the name of secret that contains Azure Storage Account Name and Key
@ -2222,7 +2241,7 @@ message PersistentVolumeSource {
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
// +optional
optional AzureFileVolumeSource azureFile = 13;
optional AzureFilePersistentVolumeSource azureFile = 13;
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
// +optional

View File

@ -6113,7 +6113,7 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Deco
}
} else {
if x.AzureFile == nil {
x.AzureFile = new(AzureFileVolumeSource)
x.AzureFile = new(AzureFilePersistentVolumeSource)
}
x.AzureFile.CodecDecodeSelf(d)
}
@ -6488,7 +6488,7 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De
}
} else {
if x.AzureFile == nil {
x.AzureFile = new(AzureFileVolumeSource)
x.AzureFile = new(AzureFilePersistentVolumeSource)
}
x.AzureFile.CodecDecodeSelf(d)
}
@ -8257,7 +8257,7 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decode
}
case "azureFile":
if x.PersistentVolumeSource.AzureFile == nil {
x.PersistentVolumeSource.AzureFile = new(AzureFileVolumeSource)
x.PersistentVolumeSource.AzureFile = new(AzureFilePersistentVolumeSource)
}
if r.TryDecodeAsNil() {
if x.AzureFile != nil {
@ -8265,7 +8265,7 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decode
}
} else {
if x.AzureFile == nil {
x.AzureFile = new(AzureFileVolumeSource)
x.AzureFile = new(AzureFilePersistentVolumeSource)
}
x.AzureFile.CodecDecodeSelf(d)
}
@ -8743,7 +8743,7 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco
x.FlexVolume.CodecDecodeSelf(d)
}
if x.PersistentVolumeSource.AzureFile == nil {
x.PersistentVolumeSource.AzureFile = new(AzureFileVolumeSource)
x.PersistentVolumeSource.AzureFile = new(AzureFilePersistentVolumeSource)
}
yyj32++
if yyhl32 {
@ -8762,7 +8762,7 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco
}
} else {
if x.AzureFile == nil {
x.AzureFile = new(AzureFileVolumeSource)
x.AzureFile = new(AzureFilePersistentVolumeSource)
}
x.AzureFile.CodecDecodeSelf(d)
}
@ -18100,6 +18100,364 @@ func (x *AzureFileVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Dec
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *AzureFilePersistentVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [4]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[2] = x.ReadOnly != false
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(4)
} else {
yynn2 = 3
for _, b := range yyq2 {
if b {
yynn2++
}
}
r.EncodeMapStart(yynn2)
yynn2 = 0
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym4 := z.EncBinary()
_ = yym4
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.SecretName))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("secretName"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym5 := z.EncBinary()
_ = yym5
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.SecretName))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.ShareName))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("shareName"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.ShareName))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
yym10 := z.EncBinary()
_ = yym10
if false {
} else {
r.EncodeBool(bool(x.ReadOnly))
}
} else {
r.EncodeBool(false)
}
} else {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("readOnly"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym11 := z.EncBinary()
_ = yym11
if false {
} else {
r.EncodeBool(bool(x.ReadOnly))
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if x.SecretNamespace == nil {
r.EncodeNil()
} else {
yy13 := *x.SecretNamespace
yym14 := z.EncBinary()
_ = yym14
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(yy13))
}
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("secretNamespace"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.SecretNamespace == nil {
r.EncodeNil()
} else {
yy15 := *x.SecretNamespace
yym16 := z.EncBinary()
_ = yym16
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(yy15))
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
z.EncSendContainerState(codecSelfer_containerMapEnd1234)
}
}
}
}
func (x *AzureFilePersistentVolumeSource) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym1 := z.DecBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeMap1234 {
yyl2 := r.ReadMapStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
} else if yyct2 == codecSelferValueTypeArray1234 {
yyl2 := r.ReadArrayStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
x.codecDecodeSelfFromArray(yyl2, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
}
}
}
func (x *AzureFilePersistentVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys3Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys3Slc
var yyhl3 bool = l >= 0
for yyj3 := 0; ; yyj3++ {
if yyhl3 {
if yyj3 >= l {
break
}
} else {
if r.CheckBreak() {
break
}
}
z.DecSendContainerState(codecSelfer_containerMapKey1234)
yys3Slc = r.DecodeBytes(yys3Slc, true, true)
yys3 := string(yys3Slc)
z.DecSendContainerState(codecSelfer_containerMapValue1234)
switch yys3 {
case "secretName":
if r.TryDecodeAsNil() {
x.SecretName = ""
} else {
yyv4 := &x.SecretName
yym5 := z.DecBinary()
_ = yym5
if false {
} else {
*((*string)(yyv4)) = r.DecodeString()
}
}
case "shareName":
if r.TryDecodeAsNil() {
x.ShareName = ""
} else {
yyv6 := &x.ShareName
yym7 := z.DecBinary()
_ = yym7
if false {
} else {
*((*string)(yyv6)) = r.DecodeString()
}
}
case "readOnly":
if r.TryDecodeAsNil() {
x.ReadOnly = false
} else {
yyv8 := &x.ReadOnly
yym9 := z.DecBinary()
_ = yym9
if false {
} else {
*((*bool)(yyv8)) = r.DecodeBool()
}
}
case "secretNamespace":
if r.TryDecodeAsNil() {
if x.SecretNamespace != nil {
x.SecretNamespace = nil
}
} else {
if x.SecretNamespace == nil {
x.SecretNamespace = new(string)
}
yym11 := z.DecBinary()
_ = yym11
if false {
} else {
*((*string)(x.SecretNamespace)) = r.DecodeString()
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
}
func (x *AzureFilePersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj12 int
var yyb12 bool
var yyhl12 bool = l >= 0
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
} else {
yyb12 = r.CheckBreak()
}
if yyb12 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.SecretName = ""
} else {
yyv13 := &x.SecretName
yym14 := z.DecBinary()
_ = yym14
if false {
} else {
*((*string)(yyv13)) = r.DecodeString()
}
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
} else {
yyb12 = r.CheckBreak()
}
if yyb12 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.ShareName = ""
} else {
yyv15 := &x.ShareName
yym16 := z.DecBinary()
_ = yym16
if false {
} else {
*((*string)(yyv15)) = r.DecodeString()
}
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
} else {
yyb12 = r.CheckBreak()
}
if yyb12 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.ReadOnly = false
} else {
yyv17 := &x.ReadOnly
yym18 := z.DecBinary()
_ = yym18
if false {
} else {
*((*bool)(yyv17)) = r.DecodeBool()
}
}
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
} else {
yyb12 = r.CheckBreak()
}
if yyb12 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
if x.SecretNamespace != nil {
x.SecretNamespace = nil
}
} else {
if x.SecretNamespace == nil {
x.SecretNamespace = new(string)
}
yym20 := z.DecBinary()
_ = yym20
if false {
} else {
*((*string)(x.SecretNamespace)) = r.DecodeString()
}
}
for {
yyj12++
if yyhl12 {
yyb12 = yyj12 > l
} else {
yyb12 = r.CheckBreak()
}
if yyb12 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj12-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *VsphereVirtualDiskVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)

View File

@ -423,7 +423,7 @@ type PersistentVolumeSource struct {
FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty" protobuf:"bytes,12,opt,name=flexVolume"`
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
// +optional
AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty" protobuf:"bytes,13,opt,name=azureFile"`
AzureFile *AzureFilePersistentVolumeSource `json:"azureFile,omitempty" protobuf:"bytes,13,opt,name=azureFile"`
// VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine
// +optional
VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" protobuf:"bytes,14,opt,name=vsphereVolume"`
@ -1169,6 +1169,22 @@ type AzureFileVolumeSource struct {
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,3,opt,name=readOnly"`
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
type AzureFilePersistentVolumeSource struct {
// the name of secret that contains Azure Storage Account Name and Key
SecretName string `json:"secretName" protobuf:"bytes,1,opt,name=secretName"`
// Share Name
ShareName string `json:"shareName" protobuf:"bytes,2,opt,name=shareName"`
// Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
// +optional
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,3,opt,name=readOnly"`
// the namespace of the secret that contains Azure Storage Account Name and Key
// default is the same as the Pod
// +optional
SecretNamespace *string `json:"secretNamespace" protobuf:"bytes,4,opt,name=secretNamespace"`
}
// Represents a vSphere volume resource.
type VsphereVirtualDiskVolumeSource struct {
// Path that identifies vSphere volume vmdk

View File

@ -83,6 +83,18 @@ func (AzureDiskVolumeSource) SwaggerDoc() map[string]string {
return map_AzureDiskVolumeSource
}
var map_AzureFilePersistentVolumeSource = map[string]string{
"": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"secretName": "the name of secret that contains Azure Storage Account Name and Key",
"shareName": "Share Name",
"readOnly": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.",
"secretNamespace": "the namespace of the secret that contains Azure Storage Account Name and Key default is the same as the Pod",
}
func (AzureFilePersistentVolumeSource) SwaggerDoc() map[string]string {
return map_AzureFilePersistentVolumeSource
}
var map_AzureFileVolumeSource = map[string]string{
"": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.",
"secretName": "the name of secret that contains Azure Storage Account Name and Key",

View File

@ -58,6 +58,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
in.(*AzureDiskVolumeSource).DeepCopyInto(out.(*AzureDiskVolumeSource))
return nil
}, InType: reflect.TypeOf(&AzureDiskVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*AzureFilePersistentVolumeSource).DeepCopyInto(out.(*AzureFilePersistentVolumeSource))
return nil
}, InType: reflect.TypeOf(&AzureFilePersistentVolumeSource{})},
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*AzureFileVolumeSource).DeepCopyInto(out.(*AzureFileVolumeSource))
return nil
@ -879,6 +883,31 @@ func (in *AzureDiskVolumeSource) DeepCopy() *AzureDiskVolumeSource {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureFilePersistentVolumeSource) DeepCopyInto(out *AzureFilePersistentVolumeSource) {
*out = *in
if in.SecretNamespace != nil {
in, out := &in.SecretNamespace, &out.SecretNamespace
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureFilePersistentVolumeSource.
func (in *AzureFilePersistentVolumeSource) DeepCopy() *AzureFilePersistentVolumeSource {
if in == nil {
return nil
}
out := new(AzureFilePersistentVolumeSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AzureFileVolumeSource) DeepCopyInto(out *AzureFileVolumeSource) {
*out = *in
@ -3656,8 +3685,8 @@ func (in *PersistentVolumeSource) DeepCopyInto(out *PersistentVolumeSource) {
if *in == nil {
*out = nil
} else {
*out = new(AzureFileVolumeSource)
**out = **in
*out = new(AzureFilePersistentVolumeSource)
(*in).DeepCopyInto(*out)
}
}
if in.VsphereVolume != nil {

View File

@ -136,7 +136,7 @@ func TestNodeAuthorizer(t *testing.T) {
AccessModes: []api.PersistentVolumeAccessMode{api.ReadOnlyMany},
Capacity: api.ResourceList{api.ResourceStorage: resource.MustParse("1")},
ClaimRef: &api.ObjectReference{Namespace: "ns", Name: "mypvc"},
PersistentVolumeSource: api.PersistentVolumeSource{AzureFile: &api.AzureFileVolumeSource{ShareName: "default", SecretName: "mypvsecret"}},
PersistentVolumeSource: api.PersistentVolumeSource{AzureFile: &api.AzureFilePersistentVolumeSource{ShareName: "default", SecretName: "mypvsecret"}},
},
}); err != nil {
t.Fatal(err)