mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-25 19:43:22 +00:00
Merge pull request #69419 from humblec/pvc-rfc-63
glusterfs: Allow admin to enable or disable custom endpoint/service names
This commit is contained in:
commit
f44a8a4cac
@ -67,7 +67,7 @@ var _ volume.Deleter = &glusterfsVolumeDeleter{}
|
|||||||
const (
|
const (
|
||||||
glusterfsPluginName = "kubernetes.io/glusterfs"
|
glusterfsPluginName = "kubernetes.io/glusterfs"
|
||||||
volPrefix = "vol_"
|
volPrefix = "vol_"
|
||||||
dynamicEpSvcPrefix = "glusterfs-dynamic-"
|
dynamicEpSvcPrefix = "glusterfs-dynamic"
|
||||||
replicaCount = 3
|
replicaCount = 3
|
||||||
durabilityType = "replicate"
|
durabilityType = "replicate"
|
||||||
secretKeyName = "key" // key name used in secret
|
secretKeyName = "key" // key name used in secret
|
||||||
@ -75,6 +75,14 @@ const (
|
|||||||
defaultGidMin = 2000
|
defaultGidMin = 2000
|
||||||
defaultGidMax = math.MaxInt32
|
defaultGidMax = math.MaxInt32
|
||||||
|
|
||||||
|
// maxCustomEpNamePrefix is the maximum number of chars.
|
||||||
|
// which can be used as ep/svc name prefix. This number is carved
|
||||||
|
// out from below formula.
|
||||||
|
// max length of name of an ep - length of pvc uuid
|
||||||
|
// where max length of name of an ep is 63 and length of uuid is 37
|
||||||
|
|
||||||
|
maxCustomEpNamePrefixLen = 26
|
||||||
|
|
||||||
// absoluteGidMin/Max are currently the same as the
|
// absoluteGidMin/Max are currently the same as the
|
||||||
// default values, but they play a different role and
|
// default values, but they play a different role and
|
||||||
// could take a different value. Only thing we need is:
|
// could take a different value. Only thing we need is:
|
||||||
@ -443,6 +451,7 @@ type provisionerConfig struct {
|
|||||||
volumeOptions []string
|
volumeOptions []string
|
||||||
volumeNamePrefix string
|
volumeNamePrefix string
|
||||||
thinPoolSnapFactor float32
|
thinPoolSnapFactor float32
|
||||||
|
customEpNamePrefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
type glusterfsVolumeProvisioner struct {
|
type glusterfsVolumeProvisioner struct {
|
||||||
@ -772,6 +781,8 @@ func (p *glusterfsVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTop
|
|||||||
func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolumeSource, size int, volID string, err error) {
|
func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolumeSource, size int, volID string, err error) {
|
||||||
var clusterIDs []string
|
var clusterIDs []string
|
||||||
customVolumeName := ""
|
customVolumeName := ""
|
||||||
|
epServiceName := ""
|
||||||
|
|
||||||
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
|
|
||||||
// GlusterFS/heketi creates volumes in units of GiB.
|
// GlusterFS/heketi creates volumes in units of GiB.
|
||||||
@ -822,7 +833,11 @@ func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolum
|
|||||||
return nil, 0, "", fmt.Errorf("failed to get cluster nodes for volume %s: %v", volume, err)
|
return nil, 0, "", fmt.Errorf("failed to get cluster nodes for volume %s: %v", volume, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
epServiceName := dynamicEpSvcPrefix + string(p.options.PVC.UID)
|
if len(p.provisionerConfig.customEpNamePrefix) == 0 {
|
||||||
|
epServiceName = string(p.options.PVC.UID)
|
||||||
|
} else {
|
||||||
|
epServiceName = p.provisionerConfig.customEpNamePrefix + "-" + string(p.options.PVC.UID)
|
||||||
|
}
|
||||||
epNamespace := p.options.PVC.Namespace
|
epNamespace := p.options.PVC.Namespace
|
||||||
endpoint, service, err := p.createEndpointService(epNamespace, epServiceName, dynamicHostIps, p.options.PVC.Name)
|
endpoint, service, err := p.createEndpointService(epNamespace, epServiceName, dynamicHostIps, p.options.PVC.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -970,6 +985,7 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa
|
|||||||
var err error
|
var err error
|
||||||
cfg.gidMin = defaultGidMin
|
cfg.gidMin = defaultGidMin
|
||||||
cfg.gidMax = defaultGidMax
|
cfg.gidMax = defaultGidMax
|
||||||
|
cfg.customEpNamePrefix = dynamicEpSvcPrefix
|
||||||
|
|
||||||
authEnabled := true
|
authEnabled := true
|
||||||
parseVolumeType := ""
|
parseVolumeType := ""
|
||||||
@ -1037,7 +1053,16 @@ func parseClassParameters(params map[string]string, kubeClient clientset.Interfa
|
|||||||
if len(v) != 0 {
|
if len(v) != 0 {
|
||||||
parseThinPoolSnapFactor = v
|
parseThinPoolSnapFactor = v
|
||||||
}
|
}
|
||||||
|
case "customepnameprefix":
|
||||||
|
// If the string has > 'maxCustomEpNamePrefixLen' chars, the final endpoint name will
|
||||||
|
// exceed the limitation of 63 chars, so fail if prefix is > 'maxCustomEpNamePrefixLen'
|
||||||
|
// characters. This is only applicable for 'customepnameprefix' string and default ep name
|
||||||
|
// string will always pass.
|
||||||
|
if len(v) <= maxCustomEpNamePrefixLen {
|
||||||
|
cfg.customEpNamePrefix = v
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("'customepnameprefix' value should be < %d characters", maxCustomEpNamePrefixLen)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, glusterfsPluginName)
|
return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, glusterfsPluginName)
|
||||||
}
|
}
|
||||||
|
@ -261,6 +261,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 2147483647,
|
gidMax: 2147483647,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -283,6 +284,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 2147483647,
|
gidMax: 2147483647,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -299,6 +301,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 2147483647,
|
gidMax: 2147483647,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -437,6 +440,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 2147483647,
|
gidMax: 2147483647,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -454,6 +458,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 5000,
|
gidMax: 5000,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -472,6 +477,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 5000,
|
gidMax: 5000,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 3}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -492,6 +498,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 5000,
|
gidMax: 5000,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -512,6 +519,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 5000,
|
gidMax: 5000,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
|
||||||
thinPoolSnapFactor: float32(1.0),
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -532,6 +540,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
gidMax: 5000,
|
gidMax: 5000,
|
||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
|
||||||
thinPoolSnapFactor: float32(50),
|
thinPoolSnapFactor: float32(50),
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -555,6 +564,7 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
|
volumeType: gapi.VolumeDurabilityInfo{Type: "disperse", Replicate: gapi.ReplicaDurability{Replica: 0}, Disperse: gapi.DisperseDurability{Data: 4, Redundancy: 2}},
|
||||||
thinPoolSnapFactor: float32(50),
|
thinPoolSnapFactor: float32(50),
|
||||||
volumeNamePrefix: "dept-dev",
|
volumeNamePrefix: "dept-dev",
|
||||||
|
customEpNamePrefix: "glusterfs-dynamic",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -645,6 +655,84 @@ func TestParseClassParameters(t *testing.T) {
|
|||||||
true, // expect error
|
true, // expect error
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"enable custom ep/svc name: customEpNamePrefix: myprefix",
|
||||||
|
map[string]string{
|
||||||
|
"resturl": "https://localhost:8080",
|
||||||
|
"restauthenabled": "false",
|
||||||
|
"gidMin": "4000",
|
||||||
|
"gidMax": "5000",
|
||||||
|
"volumetype": "replicate:4",
|
||||||
|
"customEpNamePrefix": "myprefix",
|
||||||
|
},
|
||||||
|
&secret,
|
||||||
|
false, // expect error
|
||||||
|
&provisionerConfig{
|
||||||
|
url: "https://localhost:8080",
|
||||||
|
gidMin: 4000,
|
||||||
|
gidMax: 5000,
|
||||||
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "myprefix",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"empty custom ep/svc name: customEpNamePrefix:''",
|
||||||
|
map[string]string{
|
||||||
|
"resturl": "https://localhost:8080",
|
||||||
|
"restauthenabled": "false",
|
||||||
|
"gidMin": "4000",
|
||||||
|
"gidMax": "5000",
|
||||||
|
"volumetype": "replicate:4",
|
||||||
|
"customEpNamePrefix": "",
|
||||||
|
},
|
||||||
|
&secret,
|
||||||
|
false, // expect error
|
||||||
|
&provisionerConfig{
|
||||||
|
url: "https://localhost:8080",
|
||||||
|
gidMin: 4000,
|
||||||
|
gidMax: 5000,
|
||||||
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom ep/svc name with 26 chars: customEpNamePrefix:'charstringhastwentysixchar'",
|
||||||
|
map[string]string{
|
||||||
|
"resturl": "https://localhost:8080",
|
||||||
|
"restauthenabled": "false",
|
||||||
|
"gidMin": "4000",
|
||||||
|
"gidMax": "5000",
|
||||||
|
"volumetype": "replicate:4",
|
||||||
|
"customEpNamePrefix": "charstringhastwentysixchar",
|
||||||
|
},
|
||||||
|
&secret,
|
||||||
|
false, // expect error
|
||||||
|
&provisionerConfig{
|
||||||
|
url: "https://localhost:8080",
|
||||||
|
gidMin: 4000,
|
||||||
|
gidMax: 5000,
|
||||||
|
volumeType: gapi.VolumeDurabilityInfo{Type: "replicate", Replicate: gapi.ReplicaDurability{Replica: 4}, Disperse: gapi.DisperseDurability{Data: 0, Redundancy: 0}},
|
||||||
|
thinPoolSnapFactor: float32(1.0),
|
||||||
|
customEpNamePrefix: "charstringhastwentysixchar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid customepnameprefix ( ie >26 chars) parameter",
|
||||||
|
map[string]string{
|
||||||
|
"resturl": "https://localhost:8080",
|
||||||
|
"restauthenabled": "false",
|
||||||
|
"gidMin": "4000",
|
||||||
|
"gidMax": "5000",
|
||||||
|
"volumetype": "replicate:4",
|
||||||
|
"customEpNamePrefix": "myprefixhasmorethan26characters",
|
||||||
|
},
|
||||||
|
&secret,
|
||||||
|
true, // expect error
|
||||||
|
nil,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
Loading…
Reference in New Issue
Block a user