mirror of https://github.com/k3s-io/k3s
Merge pull request #54302 from sbezverk/refactor_rbd_volume
Automatic merge from submit-queue (batch tested with PRs 54229, 54380, 54302, 54454). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Refactor RBD volume Refactor RBD Volume Persistent Volume Spec so RBD PV's SecretRef allows referencing a secret from a persistent volume in any namespace. This allows locating credentials for persistent volumes in namespaces other than the one containing the PVC. Closes #54432 ```release-note RBD Persistent Volume Sources can now reference User's Secret in namespaces other than the namespace of the bound Persistent Volume Claim ```pull/6/head
commit
16cdda003c
|
@ -68781,7 +68781,7 @@
|
|||
},
|
||||
"rbd": {
|
||||
"description": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md",
|
||||
"$ref": "#/definitions/io.k8s.api.core.v1.RBDVolumeSource"
|
||||
"$ref": "#/definitions/io.k8s.api.core.v1.RBDPersistentVolumeSource"
|
||||
},
|
||||
"scaleIO": {
|
||||
"description": "ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.",
|
||||
|
@ -69424,6 +69424,50 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.api.core.v1.RBDPersistentVolumeSource": {
|
||||
"description": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"monitors",
|
||||
"image"
|
||||
],
|
||||
"properties": {
|
||||
"fsType": {
|
||||
"description": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd",
|
||||
"type": "string"
|
||||
},
|
||||
"image": {
|
||||
"description": "The rados image name. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"type": "string"
|
||||
},
|
||||
"keyring": {
|
||||
"description": "Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"type": "string"
|
||||
},
|
||||
"monitors": {
|
||||
"description": "A collection of Ceph monitors. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"pool": {
|
||||
"description": "The rados pool name. Default is rbd. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"type": "string"
|
||||
},
|
||||
"readOnly": {
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"type": "boolean"
|
||||
},
|
||||
"secretRef": {
|
||||
"description": "SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"$ref": "#/definitions/io.k8s.api.core.v1.SecretReference"
|
||||
},
|
||||
"user": {
|
||||
"description": "The rados user name. Default is admin. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.api.core.v1.RBDVolumeSource": {
|
||||
"description": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
|
|
|
@ -20529,7 +20529,7 @@
|
|||
"description": "NFS represents an NFS mount on the host. Provisioned by an admin. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs"
|
||||
},
|
||||
"rbd": {
|
||||
"$ref": "v1.RBDVolumeSource",
|
||||
"$ref": "v1.RBDPersistentVolumeSource",
|
||||
"description": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md"
|
||||
},
|
||||
"iscsi": {
|
||||
|
@ -20737,8 +20737,8 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"v1.RBDVolumeSource": {
|
||||
"id": "v1.RBDVolumeSource",
|
||||
"v1.RBDPersistentVolumeSource": {
|
||||
"id": "v1.RBDPersistentVolumeSource",
|
||||
"description": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"monitors",
|
||||
|
@ -20773,7 +20773,7 @@
|
|||
"description": "Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"secretRef": {
|
||||
"$ref": "v1.LocalObjectReference",
|
||||
"$ref": "v1.SecretReference",
|
||||
"description": "SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"readOnly": {
|
||||
|
@ -20782,13 +20782,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"v1.LocalObjectReference": {
|
||||
"id": "v1.LocalObjectReference",
|
||||
"description": "LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace.",
|
||||
"v1.SecretReference": {
|
||||
"id": "v1.SecretReference",
|
||||
"description": "SecretReference represents a Secret Reference. It has enough information to retrieve secret in any namespace",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names"
|
||||
"description": "Name is unique within a namespace to reference a secret resource."
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string",
|
||||
"description": "Namespace defines the space within which the secret name must be unique."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -20851,6 +20855,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"v1.LocalObjectReference": {
|
||||
"id": "v1.LocalObjectReference",
|
||||
"description": "LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace.",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.CinderVolumeSource": {
|
||||
"id": "v1.CinderVolumeSource",
|
||||
"description": "Represents a cinder volume resource in Openstack. A Cinder volume must exist before mounting to a container. The volume must also be in the same region as the kubelet. Cinder volumes support ownership management and SELinux relabeling.",
|
||||
|
@ -20908,20 +20922,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"v1.SecretReference": {
|
||||
"id": "v1.SecretReference",
|
||||
"description": "SecretReference represents a Secret Reference. It has enough information to retrieve secret in any namespace",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name is unique within a namespace to reference a secret resource."
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string",
|
||||
"description": "Namespace defines the space within which the secret name must be unique."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.FCVolumeSource": {
|
||||
"id": "v1.FCVolumeSource",
|
||||
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
|
||||
|
@ -21674,6 +21674,51 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"v1.RBDVolumeSource": {
|
||||
"id": "v1.RBDVolumeSource",
|
||||
"description": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"monitors",
|
||||
"image"
|
||||
],
|
||||
"properties": {
|
||||
"monitors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "A collection of Ceph monitors. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"image": {
|
||||
"type": "string",
|
||||
"description": "The rados image name. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"fsType": {
|
||||
"type": "string",
|
||||
"description": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd"
|
||||
},
|
||||
"pool": {
|
||||
"type": "string",
|
||||
"description": "The rados pool name. Default is rbd. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"user": {
|
||||
"type": "string",
|
||||
"description": "The rados user name. Default is admin. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"keyring": {
|
||||
"type": "string",
|
||||
"description": "Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"secretRef": {
|
||||
"$ref": "v1.LocalObjectReference",
|
||||
"description": "SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
},
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.CephFSVolumeSource": {
|
||||
"id": "v1.CephFSVolumeSource",
|
||||
"description": "Represents a Ceph Filesystem mount that lasts the lifetime of a pod Cephfs volumes do not support ownership management or SELinux relabeling.",
|
||||
|
|
|
@ -7636,7 +7636,7 @@ Examples:<br>
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">rbd</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">RBD represents a Rados Block Device mount on the host that shares a pod’s lifetime. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md</a></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_rbdvolumesource">v1.RBDVolumeSource</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_rbdpersistentvolumesource">v1.RBDPersistentVolumeSource</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -8525,6 +8525,89 @@ Examples:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_rbdpersistentvolumesource">v1.RBDPersistentVolumeSource</h3>
|
||||
<div class="paragraph">
|
||||
<p>Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.</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">monitors</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">A collection of Ceph monitors. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it</a></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 array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">image</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The rados image name. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it</a></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">fsType</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: <a href="https://kubernetes.io/docs/concepts/storage/volumes#rbd">https://kubernetes.io/docs/concepts/storage/volumes#rbd</a></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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">pool</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The rados pool name. Default is rbd. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it</a></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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">user</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The rados user name. Default is admin. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it</a></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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">keyring</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it</a></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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">secretRef</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it</a></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_secretreference">v1.SecretReference</a></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">ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: <a href="https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it">https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it</a></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>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_cindervolumesource">v1.CinderVolumeSource</h3>
|
||||
|
|
|
@ -355,6 +355,20 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||
r.Keyring = "/etc/ceph/keyring"
|
||||
}
|
||||
},
|
||||
func(r *api.RBDPersistentVolumeSource, c fuzz.Continue) {
|
||||
r.RBDPool = c.RandString()
|
||||
if r.RBDPool == "" {
|
||||
r.RBDPool = "rbd"
|
||||
}
|
||||
r.RadosUser = c.RandString()
|
||||
if r.RadosUser == "" {
|
||||
r.RadosUser = "admin"
|
||||
}
|
||||
r.Keyring = c.RandString()
|
||||
if r.Keyring == "" {
|
||||
r.Keyring = "/etc/ceph/keyring"
|
||||
}
|
||||
},
|
||||
func(obj *api.HostPathVolumeSource, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj)
|
||||
types := []api.HostPathType{api.HostPathUnset, api.HostPathDirectoryOrCreate, api.HostPathDirectory,
|
||||
|
|
|
@ -64,8 +64,16 @@ func VisitPVSecretNames(pv *api.PersistentVolume, visitor Visitor) bool {
|
|||
return false
|
||||
}
|
||||
case source.RBD != nil:
|
||||
if source.RBD.SecretRef != nil && !visitor(getClaimRefNamespace(pv), source.RBD.SecretRef.Name) {
|
||||
return false
|
||||
if source.RBD.SecretRef != nil {
|
||||
// previously persisted PV objects use claimRef namespace
|
||||
ns := getClaimRefNamespace(pv)
|
||||
if len(source.RBD.SecretRef.Namespace) > 0 {
|
||||
// use the secret namespace if namespace is set
|
||||
ns = source.RBD.SecretRef.Namespace
|
||||
}
|
||||
if !visitor(ns, source.RBD.SecretRef.Name) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
case source.ScaleIO != nil:
|
||||
if source.ScaleIO.SecretRef != nil && !visitor(getClaimRefNamespace(pv), source.ScaleIO.SecretRef.Name) {
|
||||
|
|
|
@ -65,9 +65,16 @@ func TestPVSecrets(t *testing.T) {
|
|||
{Spec: api.PersistentVolumeSpec{
|
||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
RBD: &api.RBDVolumeSource{
|
||||
SecretRef: &api.LocalObjectReference{
|
||||
RBD: &api.RBDPersistentVolumeSource{
|
||||
SecretRef: &api.SecretReference{
|
||||
Name: "Spec.PersistentVolumeSource.RBD.SecretRef"}}}}},
|
||||
{Spec: api.PersistentVolumeSpec{
|
||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
RBD: &api.RBDPersistentVolumeSource{
|
||||
SecretRef: &api.SecretReference{
|
||||
Name: "Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||
Namespace: "rbdns"}}}}},
|
||||
{Spec: api.PersistentVolumeSpec{
|
||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
|
@ -141,6 +148,7 @@ func TestPVSecrets(t *testing.T) {
|
|||
"cephfs/Spec.PersistentVolumeSource.CephFS.SecretRef",
|
||||
"claimrefns/Spec.PersistentVolumeSource.FlexVolume.SecretRef",
|
||||
"claimrefns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||
"rbdns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||
"claimrefns/Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
||||
"claimrefns/Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
||||
"storageosns/Spec.PersistentVolumeSource.StorageOS.SecretRef",
|
||||
|
|
|
@ -343,7 +343,7 @@ type PersistentVolumeSource struct {
|
|||
NFS *NFSVolumeSource
|
||||
// RBD represents a Rados Block Device mount on the host that shares a pod's lifetime
|
||||
// +optional
|
||||
RBD *RBDVolumeSource
|
||||
RBD *RBDPersistentVolumeSource
|
||||
// Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
|
||||
// +optional
|
||||
Quobyte *QuobyteVolumeSource
|
||||
|
@ -1006,6 +1006,37 @@ type RBDVolumeSource struct {
|
|||
ReadOnly bool
|
||||
}
|
||||
|
||||
// Represents a Rados Block Device mount that lasts the lifetime of a pod.
|
||||
// RBD volumes support ownership management and SELinux relabeling.
|
||||
type RBDPersistentVolumeSource struct {
|
||||
// Required: CephMonitors is a collection of Ceph monitors
|
||||
CephMonitors []string
|
||||
// Required: RBDImage is the rados image name
|
||||
RBDImage string
|
||||
// Filesystem type to mount.
|
||||
// Must be a filesystem type supported by the host operating system.
|
||||
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// TODO: how do we prevent errors in the filesystem from compromising the machine
|
||||
// +optional
|
||||
FSType string
|
||||
// Optional: RadosPool is the rados pool name,default is rbd
|
||||
// +optional
|
||||
RBDPool string
|
||||
// Optional: RBDUser is the rados user name, default is admin
|
||||
// +optional
|
||||
RadosUser string
|
||||
// Optional: Keyring is the path to key ring for RBDUser, default is /etc/ceph/keyring
|
||||
// +optional
|
||||
Keyring string
|
||||
// Optional: SecretRef is reference to the authentication secret for User, default is empty.
|
||||
// +optional
|
||||
SecretRef *SecretReference
|
||||
// Optional: Defaults to false (read/write). ReadOnly here will force
|
||||
// the ReadOnly setting in VolumeMounts.
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
// Represents a cinder volume resource in Openstack. A Cinder volume
|
||||
// must exist before mounting to a container. The volume must also be
|
||||
// in the same region as the kubelet. Cinder volumes support ownership
|
||||
|
|
|
@ -368,6 +368,18 @@ func SetDefaults_RBDVolumeSource(obj *v1.RBDVolumeSource) {
|
|||
}
|
||||
}
|
||||
|
||||
func SetDefaults_RBDPersistentVolumeSource(obj *v1.RBDPersistentVolumeSource) {
|
||||
if obj.RBDPool == "" {
|
||||
obj.RBDPool = "rbd"
|
||||
}
|
||||
if obj.RadosUser == "" {
|
||||
obj.RadosUser = "admin"
|
||||
}
|
||||
if obj.Keyring == "" {
|
||||
obj.Keyring = "/etc/ceph/keyring"
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_ScaleIOVolumeSource(obj *v1.ScaleIOVolumeSource) {
|
||||
if obj.ProtectionDomain == "" {
|
||||
obj.ProtectionDomain = "default"
|
||||
|
|
|
@ -305,6 +305,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_api_ProjectedVolumeSource_To_v1_ProjectedVolumeSource,
|
||||
Convert_v1_QuobyteVolumeSource_To_api_QuobyteVolumeSource,
|
||||
Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource,
|
||||
Convert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource,
|
||||
Convert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource,
|
||||
Convert_v1_RBDVolumeSource_To_api_RBDVolumeSource,
|
||||
Convert_api_RBDVolumeSource_To_v1_RBDVolumeSource,
|
||||
Convert_v1_RangeAllocation_To_api_RangeAllocation,
|
||||
|
@ -3124,7 +3126,7 @@ func autoConvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *v1.
|
|||
out.HostPath = (*api.HostPathVolumeSource)(unsafe.Pointer(in.HostPath))
|
||||
out.Glusterfs = (*api.GlusterfsVolumeSource)(unsafe.Pointer(in.Glusterfs))
|
||||
out.NFS = (*api.NFSVolumeSource)(unsafe.Pointer(in.NFS))
|
||||
out.RBD = (*api.RBDVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.RBD = (*api.RBDPersistentVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.ISCSI = (*api.ISCSIVolumeSource)(unsafe.Pointer(in.ISCSI))
|
||||
out.Cinder = (*api.CinderVolumeSource)(unsafe.Pointer(in.Cinder))
|
||||
out.CephFS = (*api.CephFSPersistentVolumeSource)(unsafe.Pointer(in.CephFS))
|
||||
|
@ -3154,7 +3156,7 @@ func autoConvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api
|
|||
out.HostPath = (*v1.HostPathVolumeSource)(unsafe.Pointer(in.HostPath))
|
||||
out.Glusterfs = (*v1.GlusterfsVolumeSource)(unsafe.Pointer(in.Glusterfs))
|
||||
out.NFS = (*v1.NFSVolumeSource)(unsafe.Pointer(in.NFS))
|
||||
out.RBD = (*v1.RBDVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.RBD = (*v1.RBDPersistentVolumeSource)(unsafe.Pointer(in.RBD))
|
||||
out.Quobyte = (*v1.QuobyteVolumeSource)(unsafe.Pointer(in.Quobyte))
|
||||
out.ISCSI = (*v1.ISCSIVolumeSource)(unsafe.Pointer(in.ISCSI))
|
||||
out.FlexVolume = (*v1.FlexVolumeSource)(unsafe.Pointer(in.FlexVolume))
|
||||
|
@ -4062,6 +4064,40 @@ func Convert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in *api.QuobyteVo
|
|||
return autoConvert_api_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource(in *v1.RBDPersistentVolumeSource, out *api.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
out.CephMonitors = *(*[]string)(unsafe.Pointer(&in.CephMonitors))
|
||||
out.RBDImage = in.RBDImage
|
||||
out.FSType = in.FSType
|
||||
out.RBDPool = in.RBDPool
|
||||
out.RadosUser = in.RadosUser
|
||||
out.Keyring = in.Keyring
|
||||
out.SecretRef = (*api.SecretReference)(unsafe.Pointer(in.SecretRef))
|
||||
out.ReadOnly = in.ReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource is an autogenerated conversion function.
|
||||
func Convert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource(in *v1.RBDPersistentVolumeSource, out *api.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
return autoConvert_v1_RBDPersistentVolumeSource_To_api_RBDPersistentVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource(in *api.RBDPersistentVolumeSource, out *v1.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
out.CephMonitors = *(*[]string)(unsafe.Pointer(&in.CephMonitors))
|
||||
out.RBDImage = in.RBDImage
|
||||
out.FSType = in.FSType
|
||||
out.RBDPool = in.RBDPool
|
||||
out.RadosUser = in.RadosUser
|
||||
out.Keyring = in.Keyring
|
||||
out.SecretRef = (*v1.SecretReference)(unsafe.Pointer(in.SecretRef))
|
||||
out.ReadOnly = in.ReadOnly
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource is an autogenerated conversion function.
|
||||
func Convert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource(in *api.RBDPersistentVolumeSource, out *v1.RBDPersistentVolumeSource, s conversion.Scope) error {
|
||||
return autoConvert_api_RBDPersistentVolumeSource_To_v1_RBDPersistentVolumeSource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_RBDVolumeSource_To_api_RBDVolumeSource(in *v1.RBDVolumeSource, out *api.RBDVolumeSource, s conversion.Scope) error {
|
||||
out.CephMonitors = *(*[]string)(unsafe.Pointer(&in.CephMonitors))
|
||||
out.RBDImage = in.RBDImage
|
||||
|
|
|
@ -137,7 +137,7 @@ func SetObjectDefaults_PersistentVolume(in *v1.PersistentVolume) {
|
|||
SetDefaults_HostPathVolumeSource(in.Spec.PersistentVolumeSource.HostPath)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.RBD != nil {
|
||||
SetDefaults_RBDVolumeSource(in.Spec.PersistentVolumeSource.RBD)
|
||||
SetDefaults_RBDPersistentVolumeSource(in.Spec.PersistentVolumeSource.RBD)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.ISCSI != nil {
|
||||
SetDefaults_ISCSIVolumeSource(in.Spec.PersistentVolumeSource.ISCSI)
|
||||
|
|
|
@ -1088,6 +1088,17 @@ func validateRBDVolumeSource(rbd *api.RBDVolumeSource, fldPath *field.Path) fiel
|
|||
return allErrs
|
||||
}
|
||||
|
||||
func validateRBDPersistentVolumeSource(rbd *api.RBDPersistentVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(rbd.CephMonitors) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("monitors"), ""))
|
||||
}
|
||||
if len(rbd.RBDImage) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("image"), ""))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateCinderVolumeSource(cd *api.CinderVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(cd.VolumeID) == 0 {
|
||||
|
@ -1380,7 +1391,7 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
|
|||
allErrs = append(allErrs, field.Forbidden(specPath.Child("rbd"), "may not specify more than 1 volume type"))
|
||||
} else {
|
||||
numVolumes++
|
||||
allErrs = append(allErrs, validateRBDVolumeSource(pv.Spec.RBD, specPath.Child("rbd"))...)
|
||||
allErrs = append(allErrs, validateRBDPersistentVolumeSource(pv.Spec.RBD, specPath.Child("rbd"))...)
|
||||
}
|
||||
}
|
||||
if pv.Spec.Quobyte != nil {
|
||||
|
|
|
@ -571,6 +571,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
in.(*QuobyteVolumeSource).DeepCopyInto(out.(*QuobyteVolumeSource))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&QuobyteVolumeSource{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*RBDPersistentVolumeSource).DeepCopyInto(out.(*RBDPersistentVolumeSource))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&RBDPersistentVolumeSource{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*RBDVolumeSource).DeepCopyInto(out.(*RBDVolumeSource))
|
||||
return nil
|
||||
|
@ -3747,7 +3751,7 @@ func (in *PersistentVolumeSource) DeepCopyInto(out *PersistentVolumeSource) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(RBDVolumeSource)
|
||||
*out = new(RBDPersistentVolumeSource)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
@ -4815,6 +4819,36 @@ func (in *QuobyteVolumeSource) DeepCopy() *QuobyteVolumeSource {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RBDPersistentVolumeSource) DeepCopyInto(out *RBDPersistentVolumeSource) {
|
||||
*out = *in
|
||||
if in.CephMonitors != nil {
|
||||
in, out := &in.CephMonitors, &out.CephMonitors
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RBDPersistentVolumeSource.
|
||||
func (in *RBDPersistentVolumeSource) DeepCopy() *RBDPersistentVolumeSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RBDPersistentVolumeSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RBDVolumeSource) DeepCopyInto(out *RBDVolumeSource) {
|
||||
*out = *in
|
||||
|
|
|
@ -898,6 +898,19 @@ func printRBDVolumeSource(rbd *api.RBDVolumeSource, w PrefixWriter) {
|
|||
rbd.CephMonitors, rbd.RBDImage, rbd.FSType, rbd.RBDPool, rbd.RadosUser, rbd.Keyring, rbd.SecretRef, rbd.ReadOnly)
|
||||
}
|
||||
|
||||
func printRBDPersistentVolumeSource(rbd *api.RBDPersistentVolumeSource, w PrefixWriter) {
|
||||
w.Write(LEVEL_2, "Type:\tRBD (a Rados Block Device mount on the host that shares a pod's lifetime)\n"+
|
||||
" CephMonitors:\t%v\n"+
|
||||
" RBDImage:\t%v\n"+
|
||||
" FSType:\t%v\n"+
|
||||
" RBDPool:\t%v\n"+
|
||||
" RadosUser:\t%v\n"+
|
||||
" Keyring:\t%v\n"+
|
||||
" SecretRef:\t%v\n"+
|
||||
" ReadOnly:\t%v\n",
|
||||
rbd.CephMonitors, rbd.RBDImage, rbd.FSType, rbd.RBDPool, rbd.RadosUser, rbd.Keyring, rbd.SecretRef, rbd.ReadOnly)
|
||||
}
|
||||
|
||||
func printDownwardAPIVolumeSource(d *api.DownwardAPIVolumeSource, w PrefixWriter) {
|
||||
w.Write(LEVEL_2, "Type:\tDownwardAPI (a volume populated by information about the pod)\n Items:\n")
|
||||
for _, mapping := range d.Items {
|
||||
|
@ -1108,7 +1121,7 @@ func describePersistentVolume(pv *api.PersistentVolume, events *api.EventList) (
|
|||
case pv.Spec.Glusterfs != nil:
|
||||
printGlusterfsVolumeSource(pv.Spec.Glusterfs, w)
|
||||
case pv.Spec.RBD != nil:
|
||||
printRBDVolumeSource(pv.Spec.RBD, w)
|
||||
printRBDPersistentVolumeSource(pv.Spec.RBD, w)
|
||||
case pv.Spec.Quobyte != nil:
|
||||
printQuobyteVolumeSource(pv.Spec.Quobyte, w)
|
||||
case pv.Spec.VsphereVolume != nil:
|
||||
|
|
|
@ -776,7 +776,7 @@ func TestPersistentVolumeDescriber(t *testing.T) {
|
|||
ObjectMeta: metav1.ObjectMeta{Name: "bar"},
|
||||
Spec: api.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
RBD: &api.RBDVolumeSource{},
|
||||
RBD: &api.RBDPersistentVolumeSource{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -39,7 +39,7 @@ type diskManager interface {
|
|||
// Detaches the disk from the kubelet's host machine.
|
||||
DetachDisk(disk rbdUnmounter, mntPath string) error
|
||||
// Creates a rbd image
|
||||
CreateImage(provisioner *rbdVolumeProvisioner) (r *v1.RBDVolumeSource, volumeSizeGB int, err error)
|
||||
CreateImage(provisioner *rbdVolumeProvisioner) (r *v1.RBDPersistentVolumeSource, volumeSizeGB int, err error)
|
||||
// Deletes a rbd image
|
||||
DeleteImage(deleter *rbdVolumeDeleter) error
|
||||
}
|
||||
|
|
|
@ -78,15 +78,19 @@ func (plugin *rbdPlugin) GetPluginName() string {
|
|||
}
|
||||
|
||||
func (plugin *rbdPlugin) GetVolumeName(spec *volume.Spec) (string, error) {
|
||||
volumeSource, _, err := getVolumeSource(spec)
|
||||
mon, err := getVolumeSourceMonitors(spec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
img, err := getVolumeSourceImage(spec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%v:%v",
|
||||
volumeSource.CephMonitors,
|
||||
volumeSource.RBDImage), nil
|
||||
mon,
|
||||
img), nil
|
||||
}
|
||||
|
||||
func (plugin *rbdPlugin) CanSupport(spec *volume.Spec) bool {
|
||||
|
@ -117,55 +121,79 @@ func (plugin *rbdPlugin) GetAccessModes() []v1.PersistentVolumeAccessMode {
|
|||
}
|
||||
|
||||
func (plugin *rbdPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.Mounter, error) {
|
||||
var secret string
|
||||
var err error
|
||||
source, _ := plugin.getRBDVolumeSource(spec)
|
||||
|
||||
if source.SecretRef != nil {
|
||||
if secret, err = parsePodSecret(pod, source.SecretRef.Name, plugin.host.GetKubeClient()); err != nil {
|
||||
glog.Errorf("Couldn't get secret from %v/%v", pod.Namespace, source.SecretRef)
|
||||
secretName, secretNs, err := getSecretNameAndNamespace(spec, pod.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secret := ""
|
||||
if len(secretName) > 0 && len(secretNs) > 0 {
|
||||
// if secret is provideded, retrieve it
|
||||
kubeClient := plugin.host.GetKubeClient()
|
||||
if kubeClient == nil {
|
||||
return nil, fmt.Errorf("Cannot get kube client")
|
||||
}
|
||||
secrets, err := kubeClient.Core().Secrets(secretNs).Get(secretName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Couldn't get secret %v/%v err: %v", secretNs, secretName, err)
|
||||
return nil, err
|
||||
}
|
||||
for _, data := range secrets.Data {
|
||||
secret = string(data)
|
||||
}
|
||||
}
|
||||
|
||||
// Inject real implementations here, test through the internal function.
|
||||
return plugin.newMounterInternal(spec, pod.UID, &RBDUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()), secret)
|
||||
}
|
||||
|
||||
func (plugin *rbdPlugin) getRBDVolumeSource(spec *volume.Spec) (*v1.RBDVolumeSource, bool) {
|
||||
// rbd volumes used directly in a pod have a ReadOnly flag set by the pod author.
|
||||
// rbd volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD, spec.Volume.RBD.ReadOnly
|
||||
} else {
|
||||
return spec.PersistentVolume.Spec.RBD, spec.ReadOnly
|
||||
}
|
||||
}
|
||||
|
||||
func (plugin *rbdPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec, secret string) (volume.Mounter, error) {
|
||||
source, readOnly := plugin.getRBDVolumeSource(spec)
|
||||
pool := source.RBDPool
|
||||
id := source.RadosUser
|
||||
keyring := source.Keyring
|
||||
mon, err := getVolumeSourceMonitors(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
img, err := getVolumeSourceImage(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fstype, err := getVolumeSourceFSType(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool, err := getVolumeSourcePool(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id, err := getVolumeSourceUser(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyring, err := getVolumeSourceKeyRing(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ro, err := getVolumeSourceReadOnly(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &rbdMounter{
|
||||
rbd: &rbd{
|
||||
podUID: podUID,
|
||||
volName: spec.Name(),
|
||||
Image: source.RBDImage,
|
||||
Image: img,
|
||||
Pool: pool,
|
||||
ReadOnly: readOnly,
|
||||
ReadOnly: ro,
|
||||
manager: manager,
|
||||
mounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: exec},
|
||||
exec: exec,
|
||||
plugin: plugin,
|
||||
MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, spec.Name(), plugin.host)),
|
||||
},
|
||||
Mon: source.CephMonitors,
|
||||
Mon: mon,
|
||||
Id: id,
|
||||
Keyring: keyring,
|
||||
Secret: secret,
|
||||
fsType: source.FSType,
|
||||
fsType: fstype,
|
||||
mountOptions: volume.MountOptionFromSpec(spec),
|
||||
}, nil
|
||||
}
|
||||
|
@ -289,8 +317,9 @@ func (r *rbdVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
|
|||
var err error
|
||||
adminSecretName := ""
|
||||
adminSecretNamespace := rbdDefaultAdminSecretNamespace
|
||||
secretName := ""
|
||||
secret := ""
|
||||
secretName := ""
|
||||
secretNamespace := ""
|
||||
imageFormat := rbdImageFormat2
|
||||
fstype := ""
|
||||
|
||||
|
@ -313,6 +342,8 @@ func (r *rbdVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
|
|||
r.Pool = v
|
||||
case "usersecretname":
|
||||
secretName = v
|
||||
case "usersecretnamespace":
|
||||
secretNamespace = v
|
||||
case "imageformat":
|
||||
imageFormat = v
|
||||
case "imagefeatures":
|
||||
|
@ -370,8 +401,9 @@ func (r *rbdVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
|
|||
glog.Infof("successfully created rbd image %q", image)
|
||||
pv := new(v1.PersistentVolume)
|
||||
metav1.SetMetaDataAnnotation(&pv.ObjectMeta, volumehelper.VolumeDynamicallyCreatedByKey, "rbd-dynamic-provisioner")
|
||||
rbd.SecretRef = new(v1.LocalObjectReference)
|
||||
rbd.SecretRef = new(v1.SecretReference)
|
||||
rbd.SecretRef.Name = secretName
|
||||
rbd.SecretRef.Namespace = secretNamespace
|
||||
rbd.RadosUser = r.Id
|
||||
rbd.FSType = fstype
|
||||
pv.Spec.PersistentVolumeSource.RBD = rbd
|
||||
|
@ -486,16 +518,83 @@ func (c *rbdUnmounter) TearDownAt(dir string) error {
|
|||
return diskTearDown(c.manager, *c, dir, c.mounter)
|
||||
}
|
||||
|
||||
func getVolumeSource(
|
||||
spec *volume.Spec) (*v1.RBDVolumeSource, bool, error) {
|
||||
func getVolumeSourceMonitors(spec *volume.Spec) ([]string, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD, spec.Volume.RBD.ReadOnly, nil
|
||||
return spec.Volume.RBD.CephMonitors, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
return spec.PersistentVolume.Spec.RBD, spec.ReadOnly, nil
|
||||
return spec.PersistentVolume.Spec.RBD.CephMonitors, nil
|
||||
}
|
||||
|
||||
return nil, false, fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
return nil, fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
}
|
||||
|
||||
func getVolumeSourceImage(spec *volume.Spec) (string, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD.RBDImage, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
return spec.PersistentVolume.Spec.RBD.RBDImage, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
}
|
||||
|
||||
func getVolumeSourceFSType(spec *volume.Spec) (string, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD.FSType, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
return spec.PersistentVolume.Spec.RBD.FSType, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
}
|
||||
|
||||
func getVolumeSourcePool(spec *volume.Spec) (string, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD.RBDPool, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
return spec.PersistentVolume.Spec.RBD.RBDPool, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
}
|
||||
|
||||
func getVolumeSourceUser(spec *volume.Spec) (string, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD.RadosUser, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
return spec.PersistentVolume.Spec.RBD.RadosUser, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
}
|
||||
|
||||
func getVolumeSourceKeyRing(spec *volume.Spec) (string, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD.Keyring, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
return spec.PersistentVolume.Spec.RBD.Keyring, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
}
|
||||
|
||||
func getVolumeSourceReadOnly(spec *volume.Spec) (bool, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
return spec.Volume.RBD.ReadOnly, nil
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
// rbd volumes used as a PersistentVolume gets the ReadOnly flag indirectly through
|
||||
// the persistent-claim volume used to mount the PV
|
||||
return spec.ReadOnly, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("Spec does not reference a RBD volume type")
|
||||
}
|
||||
|
||||
func parsePodSecret(pod *v1.Pod, secretName string, kubeClient clientset.Interface) (string, error) {
|
||||
|
@ -531,3 +630,26 @@ func parseSecretMap(secretMap map[string]string) (string, error) {
|
|||
// If not found, the last secret in the map wins as done before
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
func getSecretNameAndNamespace(spec *volume.Spec, defaultNamespace string) (string, string, error) {
|
||||
if spec.Volume != nil && spec.Volume.RBD != nil {
|
||||
localSecretRef := spec.Volume.RBD.SecretRef
|
||||
if localSecretRef != nil {
|
||||
return localSecretRef.Name, defaultNamespace, nil
|
||||
}
|
||||
return "", "", nil
|
||||
|
||||
} else if spec.PersistentVolume != nil &&
|
||||
spec.PersistentVolume.Spec.RBD != nil {
|
||||
secretRef := spec.PersistentVolume.Spec.RBD.SecretRef
|
||||
secretNs := defaultNamespace
|
||||
if secretRef != nil {
|
||||
if len(secretRef.Namespace) != 0 {
|
||||
secretNs = secretRef.Namespace
|
||||
}
|
||||
return secretRef.Name, secretNs, nil
|
||||
}
|
||||
return "", "", nil
|
||||
}
|
||||
return "", "", fmt.Errorf("Spec does not reference an RBD volume type")
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -92,7 +93,7 @@ func (fake *fakeDiskManager) DetachDisk(c rbdUnmounter, mntPath string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (fake *fakeDiskManager) CreateImage(provisioner *rbdVolumeProvisioner) (r *v1.RBDVolumeSource, volumeSizeGB int, err error) {
|
||||
func (fake *fakeDiskManager) CreateImage(provisioner *rbdVolumeProvisioner) (r *v1.RBDPersistentVolumeSource, volumeSizeGB int, err error) {
|
||||
return nil, 0, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
|
@ -180,7 +181,7 @@ func TestPluginPersistentVolume(t *testing.T) {
|
|||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||
RBD: &v1.RBDVolumeSource{
|
||||
RBD: &v1.RBDPersistentVolumeSource{
|
||||
CephMonitors: []string{"a", "b"},
|
||||
RBDImage: "bar",
|
||||
FSType: "ext4",
|
||||
|
@ -205,7 +206,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
|||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||
RBD: &v1.RBDVolumeSource{
|
||||
RBD: &v1.RBDPersistentVolumeSource{
|
||||
CephMonitors: []string{"a", "b"},
|
||||
RBDImage: "bar",
|
||||
FSType: "ext4",
|
||||
|
@ -329,3 +330,35 @@ func TestPersistAndLoadRBD(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSecretNameAndNamespace(t *testing.T) {
|
||||
secretName := "test-secret-name"
|
||||
secretNamespace := "test-secret-namespace"
|
||||
|
||||
volSpec := &volume.Spec{
|
||||
PersistentVolume: &v1.PersistentVolume{
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||
RBD: &v1.RBDPersistentVolumeSource{
|
||||
CephMonitors: []string{"a", "b"},
|
||||
RBDImage: "bar",
|
||||
FSType: "ext4",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
secretRef := new(v1.SecretReference)
|
||||
secretRef.Name = secretName
|
||||
secretRef.Namespace = secretNamespace
|
||||
volSpec.PersistentVolume.Spec.PersistentVolumeSource.RBD.SecretRef = secretRef
|
||||
|
||||
foundSecretName, foundSecretNamespace, err := getSecretNameAndNamespace(volSpec, "default")
|
||||
if err != nil {
|
||||
t.Errorf("getSecretNameAndNamespace failed to get Secret's name and namespace: %v", err)
|
||||
}
|
||||
if strings.Compare(secretName, foundSecretName) != 0 || strings.Compare(secretNamespace, foundSecretNamespace) != 0 {
|
||||
t.Errorf("getSecretNameAndNamespace returned incorrect values, expected %s and %s but got %s and %s", secretName, secretNamespace, foundSecretName, foundSecretNamespace)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ func (util *RBDUtil) DetachDisk(c rbdUnmounter, mntPath string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (util *RBDUtil) CreateImage(p *rbdVolumeProvisioner) (r *v1.RBDVolumeSource, size int, err error) {
|
||||
func (util *RBDUtil) CreateImage(p *rbdVolumeProvisioner) (r *v1.RBDPersistentVolumeSource, size int, err error) {
|
||||
var output []byte
|
||||
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||
volSizeBytes := capacity.Value()
|
||||
|
@ -400,7 +400,7 @@ func (util *RBDUtil) CreateImage(p *rbdVolumeProvisioner) (r *v1.RBDVolumeSource
|
|||
return nil, 0, fmt.Errorf("failed to create rbd image: %v, command output: %s", err, string(output))
|
||||
}
|
||||
|
||||
return &v1.RBDVolumeSource{
|
||||
return &v1.RBDPersistentVolumeSource{
|
||||
CephMonitors: p.rbdMounter.Mon,
|
||||
RBDImage: p.rbdMounter.Image,
|
||||
RBDPool: p.rbdMounter.Pool,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2287,7 +2287,7 @@ message PersistentVolumeSource {
|
|||
// RBD represents a Rados Block Device mount on the host that shares a pod's lifetime.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md
|
||||
// +optional
|
||||
optional RBDVolumeSource rbd = 6;
|
||||
optional RBDPersistentVolumeSource rbd = 6;
|
||||
|
||||
// ISCSI represents an ISCSI Disk resource that is attached to a
|
||||
// kubelet's host machine and then exposed to the pod. Provisioned by an admin.
|
||||
|
@ -3157,6 +3157,57 @@ message QuobyteVolumeSource {
|
|||
optional string group = 5;
|
||||
}
|
||||
|
||||
// Represents a Rados Block Device mount that lasts the lifetime of a pod.
|
||||
// RBD volumes support ownership management and SELinux relabeling.
|
||||
message RBDPersistentVolumeSource {
|
||||
// A collection of Ceph monitors.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
repeated string monitors = 1;
|
||||
|
||||
// The rados image name.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
optional string image = 2;
|
||||
|
||||
// Filesystem type of the volume that you want to mount.
|
||||
// Tip: Ensure that the filesystem type is supported by the host operating system.
|
||||
// Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
|
||||
// TODO: how do we prevent errors in the filesystem from compromising the machine
|
||||
// +optional
|
||||
optional string fsType = 3;
|
||||
|
||||
// The rados pool name.
|
||||
// Default is rbd.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
optional string pool = 4;
|
||||
|
||||
// The rados user name.
|
||||
// Default is admin.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
optional string user = 5;
|
||||
|
||||
// Keyring is the path to key ring for RBDUser.
|
||||
// Default is /etc/ceph/keyring.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
optional string keyring = 6;
|
||||
|
||||
// SecretRef is name of the authentication secret for RBDUser. If provided
|
||||
// overrides keyring.
|
||||
// Default is nil.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
optional SecretReference secretRef = 7;
|
||||
|
||||
// ReadOnly here will force the ReadOnly setting in VolumeMounts.
|
||||
// Defaults to false.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
optional bool readOnly = 8;
|
||||
}
|
||||
|
||||
// Represents a Rados Block Device mount that lasts the lifetime of a pod.
|
||||
// RBD volumes support ownership management and SELinux relabeling.
|
||||
message RBDVolumeSource {
|
||||
|
|
|
@ -398,7 +398,7 @@ type PersistentVolumeSource struct {
|
|||
// RBD represents a Rados Block Device mount on the host that shares a pod's lifetime.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md
|
||||
// +optional
|
||||
RBD *RBDVolumeSource `json:"rbd,omitempty" protobuf:"bytes,6,opt,name=rbd"`
|
||||
RBD *RBDPersistentVolumeSource `json:"rbd,omitempty" protobuf:"bytes,6,opt,name=rbd"`
|
||||
// ISCSI represents an ISCSI Disk resource that is attached to a
|
||||
// kubelet's host machine and then exposed to the pod. Provisioned by an admin.
|
||||
// +optional
|
||||
|
@ -838,6 +838,50 @@ type RBDVolumeSource struct {
|
|||
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,8,opt,name=readOnly"`
|
||||
}
|
||||
|
||||
// Represents a Rados Block Device mount that lasts the lifetime of a pod.
|
||||
// RBD volumes support ownership management and SELinux relabeling.
|
||||
type RBDPersistentVolumeSource struct {
|
||||
// A collection of Ceph monitors.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
CephMonitors []string `json:"monitors" protobuf:"bytes,1,rep,name=monitors"`
|
||||
// The rados image name.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
RBDImage string `json:"image" protobuf:"bytes,2,opt,name=image"`
|
||||
// Filesystem type of the volume that you want to mount.
|
||||
// Tip: Ensure that the filesystem type is supported by the host operating system.
|
||||
// Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
|
||||
// TODO: how do we prevent errors in the filesystem from compromising the machine
|
||||
// +optional
|
||||
FSType string `json:"fsType,omitempty" protobuf:"bytes,3,opt,name=fsType"`
|
||||
// The rados pool name.
|
||||
// Default is rbd.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
RBDPool string `json:"pool,omitempty" protobuf:"bytes,4,opt,name=pool"`
|
||||
// The rados user name.
|
||||
// Default is admin.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
RadosUser string `json:"user,omitempty" protobuf:"bytes,5,opt,name=user"`
|
||||
// Keyring is the path to key ring for RBDUser.
|
||||
// Default is /etc/ceph/keyring.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
Keyring string `json:"keyring,omitempty" protobuf:"bytes,6,opt,name=keyring"`
|
||||
// SecretRef is name of the authentication secret for RBDUser. If provided
|
||||
// overrides keyring.
|
||||
// Default is nil.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
SecretRef *SecretReference `json:"secretRef,omitempty" protobuf:"bytes,7,opt,name=secretRef"`
|
||||
// ReadOnly here will force the ReadOnly setting in VolumeMounts.
|
||||
// Defaults to false.
|
||||
// More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it
|
||||
// +optional
|
||||
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,8,opt,name=readOnly"`
|
||||
}
|
||||
|
||||
// Represents a cinder volume resource in Openstack.
|
||||
// A Cinder volume must exist before mounting to a container.
|
||||
// The volume must also be in the same region as the kubelet.
|
||||
|
|
|
@ -1571,6 +1571,22 @@ func (QuobyteVolumeSource) SwaggerDoc() map[string]string {
|
|||
return map_QuobyteVolumeSource
|
||||
}
|
||||
|
||||
var map_RBDPersistentVolumeSource = map[string]string{
|
||||
"": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.",
|
||||
"monitors": "A collection of Ceph monitors. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"image": "The rados image name. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd",
|
||||
"pool": "The rados pool name. Default is rbd. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"user": "The rados user name. Default is admin. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"keyring": "Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"secretRef": "SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
"readOnly": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
}
|
||||
|
||||
func (RBDPersistentVolumeSource) SwaggerDoc() map[string]string {
|
||||
return map_RBDPersistentVolumeSource
|
||||
}
|
||||
|
||||
var map_RBDVolumeSource = map[string]string{
|
||||
"": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.",
|
||||
"monitors": "A collection of Ceph monitors. More info: https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md#how-to-use-it",
|
||||
|
|
|
@ -571,6 +571,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||
in.(*QuobyteVolumeSource).DeepCopyInto(out.(*QuobyteVolumeSource))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&QuobyteVolumeSource{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*RBDPersistentVolumeSource).DeepCopyInto(out.(*RBDPersistentVolumeSource))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&RBDPersistentVolumeSource{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*RBDVolumeSource).DeepCopyInto(out.(*RBDVolumeSource))
|
||||
return nil
|
||||
|
@ -3733,7 +3737,7 @@ func (in *PersistentVolumeSource) DeepCopyInto(out *PersistentVolumeSource) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(RBDVolumeSource)
|
||||
*out = new(RBDPersistentVolumeSource)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
@ -4801,6 +4805,36 @@ func (in *QuobyteVolumeSource) DeepCopy() *QuobyteVolumeSource {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RBDPersistentVolumeSource) DeepCopyInto(out *RBDPersistentVolumeSource) {
|
||||
*out = *in
|
||||
if in.CephMonitors != nil {
|
||||
in, out := &in.CephMonitors, &out.CephMonitors
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RBDPersistentVolumeSource.
|
||||
func (in *RBDPersistentVolumeSource) DeepCopy() *RBDPersistentVolumeSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RBDPersistentVolumeSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RBDVolumeSource) DeepCopyInto(out *RBDVolumeSource) {
|
||||
*out = *in
|
||||
|
|
Loading…
Reference in New Issue