mirror of https://github.com/k3s-io/k3s
Adding Tenant to QuobyteVolumeSource
Adds the tenant id to the QuobyteVolumeSource type and updates the quobyte api client to support looking up volume ids.pull/564/head
parent
54dc9db17b
commit
cc71b0aebd
|
@ -2990,8 +2990,8 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/quobyte/api",
|
||||
"Comment": "v0.1.1-4-g206ef832283c1a",
|
||||
"Rev": "206ef832283c1a0144bbc762be2634d49987b5ff"
|
||||
"Comment": "v0.1.2",
|
||||
"Rev": "9cfd29338dd9fdaaf956b7082e5550aab5fe3841"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rancher/go-rancher/client",
|
||||
|
|
|
@ -88245,6 +88245,10 @@
|
|||
"description": "Registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes",
|
||||
"type": "string"
|
||||
},
|
||||
"tenant": {
|
||||
"description": "Tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin",
|
||||
"type": "string"
|
||||
},
|
||||
"user": {
|
||||
"description": "User to map volume access to Defaults to serivceaccount user",
|
||||
"type": "string"
|
||||
|
|
|
@ -918,6 +918,11 @@ type QuobyteVolumeSource struct {
|
|||
// Default is no group
|
||||
// +optional
|
||||
Group string
|
||||
|
||||
// Tenant owning the given Quobyte volume in the Backend
|
||||
// Used with dynamically provisioned Quobyte volumes, value is set by the plugin
|
||||
// +optional
|
||||
Tenant string
|
||||
}
|
||||
|
||||
// Represents a Glusterfs mount that lasts the lifetime of a pod.
|
||||
|
|
|
@ -5989,6 +5989,7 @@ func autoConvert_v1_QuobyteVolumeSource_To_core_QuobyteVolumeSource(in *v1.Quoby
|
|||
out.ReadOnly = in.ReadOnly
|
||||
out.User = in.User
|
||||
out.Group = in.Group
|
||||
out.Tenant = in.Tenant
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -6003,6 +6004,7 @@ func autoConvert_core_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in *core.Quo
|
|||
out.ReadOnly = in.ReadOnly
|
||||
out.User = in.User
|
||||
out.Group = in.Group
|
||||
out.Tenant = in.Tenant
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -873,6 +873,10 @@ func validateQuobyteVolumeSource(quobyte *core.QuobyteVolumeSource, fldPath *fie
|
|||
allErrs := field.ErrorList{}
|
||||
if len(quobyte.Registry) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("registry"), "must be a host:port pair or multiple pairs separated by commas"))
|
||||
} else if len(quobyte.Tenant) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("tenant"), "must be a UUID provided by the configuration and may not be omitted "))
|
||||
} else if len(quobyte.Tenant) >= 65 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("tenant"), "must be a UUID and may not exceed a length of 64 characters"))
|
||||
} else {
|
||||
for _, hostPortPair := range strings.Split(quobyte.Registry, ",") {
|
||||
if _, _, err := net.SplitHostPort(hostPortPair); err != nil {
|
||||
|
|
|
@ -3379,6 +3379,7 @@ func TestValidateVolumes(t *testing.T) {
|
|||
ReadOnly: false,
|
||||
User: "root",
|
||||
Group: "root",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3390,6 +3391,7 @@ func TestValidateVolumes(t *testing.T) {
|
|||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Volume: "/test",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3406,6 +3408,7 @@ func TestValidateVolumes(t *testing.T) {
|
|||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry7861",
|
||||
Volume: "/test",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3422,6 +3425,7 @@ func TestValidateVolumes(t *testing.T) {
|
|||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861,reg2",
|
||||
Volume: "/test",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3437,6 +3441,7 @@ func TestValidateVolumes(t *testing.T) {
|
|||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3445,6 +3450,40 @@ func TestValidateVolumes(t *testing.T) {
|
|||
field: "quobyte.volume",
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "empty tenant quobyte",
|
||||
vol: core.Volume{
|
||||
Name: "quobyte",
|
||||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861,reg2",
|
||||
Volume: "/test",
|
||||
Tenant: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
errs: []verr{{
|
||||
etype: field.ErrorTypeRequired,
|
||||
field: "quobyte.tenant",
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "too long tenant quobyte",
|
||||
vol: core.Volume{
|
||||
Name: "quobyte",
|
||||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861,reg2",
|
||||
Volume: "/test",
|
||||
Tenant: "this is too long to be a valid uuid so this test has to fail on the maximum length validation of the tenant.",
|
||||
},
|
||||
},
|
||||
},
|
||||
errs: []verr{{
|
||||
etype: field.ErrorTypeRequired,
|
||||
field: "quobyte.tenant",
|
||||
}},
|
||||
},
|
||||
// AzureDisk
|
||||
{
|
||||
name: "valid AzureDisk",
|
||||
|
|
|
@ -326,6 +326,7 @@ func (plugin *quobytePlugin) newDeleterInternal(spec *volume.Spec) (volume.Delet
|
|||
group: source.Group,
|
||||
volume: source.Volume,
|
||||
plugin: plugin,
|
||||
tenant: source.Tenant,
|
||||
},
|
||||
registry: source.Registry,
|
||||
readOnly: readOnly,
|
||||
|
@ -424,6 +425,7 @@ func (provisioner *quobyteVolumeProvisioner) Provision(selectedNode *v1.Node, al
|
|||
v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)),
|
||||
}
|
||||
pv.Spec.MountOptions = provisioner.options.MountOptions
|
||||
pv.Spec.PersistentVolumeSource.Quobyte.Tenant = provisioner.tenant
|
||||
return pv, nil
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3421,6 +3421,11 @@ message QuobyteVolumeSource {
|
|||
// Default is no group
|
||||
// +optional
|
||||
optional string group = 5;
|
||||
|
||||
// Tenant owning the given Quobyte volume in the Backend
|
||||
// Used with dynamically provisioned Quobyte volumes, value is set by the plugin
|
||||
// +optional
|
||||
optional string tenant = 6;
|
||||
}
|
||||
|
||||
// Represents a Rados Block Device mount that lasts the lifetime of a pod.
|
||||
|
|
|
@ -955,6 +955,11 @@ type QuobyteVolumeSource struct {
|
|||
// Default is no group
|
||||
// +optional
|
||||
Group string `json:"group,omitempty" protobuf:"bytes,5,opt,name=group"`
|
||||
|
||||
// Tenant owning the given Quobyte volume in the Backend
|
||||
// Used with dynamically provisioned Quobyte volumes, value is set by the plugin
|
||||
// +optional
|
||||
Tenant string `json:"tenant,omitempty" protobuf:"bytes,6,opt,name=tenant"`
|
||||
}
|
||||
|
||||
// FlexPersistentVolumeSource represents a generic persistent volume resource that is
|
||||
|
|
|
@ -1678,6 +1678,7 @@ var map_QuobyteVolumeSource = map[string]string{
|
|||
"readOnly": "ReadOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false.",
|
||||
"user": "User to map volume access to Defaults to serivceaccount user",
|
||||
"group": "Group to map volume access to Default is no group",
|
||||
"tenant": "Tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin",
|
||||
}
|
||||
|
||||
func (QuobyteVolumeSource) SwaggerDoc() map[string]string {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
package quobyte
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
)
|
||||
|
@ -15,6 +14,8 @@ const (
|
|||
RetryOncePerTarget string = "ONCE_PER_TARGET"
|
||||
)
|
||||
|
||||
var UUIDValidator = regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
|
||||
|
||||
type QuobyteClient struct {
|
||||
client *http.Client
|
||||
url string
|
||||
|
@ -45,24 +46,50 @@ func NewQuobyteClient(url string, username string, password string) *QuobyteClie
|
|||
// CreateVolume creates a new Quobyte volume. Its root directory will be owned by given user and group
|
||||
func (client QuobyteClient) CreateVolume(request *CreateVolumeRequest) (string, error) {
|
||||
var response volumeUUID
|
||||
|
||||
if request.TenantID != "" && !IsValidUUID(request.TenantID) {
|
||||
log.Printf("Tenant name resolution: Resolving %s to UUID\n", request.TenantID)
|
||||
tenantUUID, err := client.ResolveTenantNameToUUID(request.TenantID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
request.TenantID = tenantUUID
|
||||
tenantUUID, err := client.GetTenantUUID(request.TenantID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
request.TenantID = tenantUUID
|
||||
|
||||
if err := client.sendRequest("createVolume", request, &response); err != nil {
|
||||
if err = client.sendRequest("createVolume", request, &response); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return response.VolumeUUID, nil
|
||||
}
|
||||
|
||||
// GetVolumeUUID resolves the volumeUUID for the given volume and tenant name.
|
||||
// This method should be used when it is not clear if the given string is volume UUID or Name.
|
||||
func (client QuobyteClient) GetVolumeUUID(volume, tenant string) (string, error) {
|
||||
if len(volume) != 0 && !IsValidUUID(volume) {
|
||||
tenantUUID, err := client.GetTenantUUID(tenant)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
volUUID, err := client.ResolveVolumeNameToUUID(volume, tenantUUID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return volUUID, nil
|
||||
}
|
||||
return volume, nil
|
||||
}
|
||||
|
||||
// GetTenantUUID resolves the tenatnUUID for the given name
|
||||
// This method should be used when it is not clear if the given string is Tenant UUID or Name.
|
||||
func (client QuobyteClient) GetTenantUUID(tenant string) (string, error) {
|
||||
if len(tenant) != 0 && !IsValidUUID(tenant) {
|
||||
tenantUUID, err := client.ResolveTenantNameToUUID(tenant)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tenantUUID, nil
|
||||
}
|
||||
return tenant, nil
|
||||
}
|
||||
|
||||
// ResolveVolumeNameToUUID resolves a volume name to a UUID
|
||||
func (client *QuobyteClient) ResolveVolumeNameToUUID(volumeName, tenant string) (string, error) {
|
||||
request := &resolveVolumeNameRequest{
|
||||
|
@ -77,6 +104,18 @@ func (client *QuobyteClient) ResolveVolumeNameToUUID(volumeName, tenant string)
|
|||
return response.VolumeUUID, nil
|
||||
}
|
||||
|
||||
// DeleteVolumeByResolvingNamesToUUID deletes the volume by resolving the volume name and tenant name to
|
||||
// respective UUID if required.
|
||||
// This method should be used if the given volume, tenant information is name or UUID.
|
||||
func (client *QuobyteClient) DeleteVolumeByResolvingNamesToUUID(volume, tenant string) error {
|
||||
volumeUUID, err := client.GetVolumeUUID(volume, tenant)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.DeleteVolume(volumeUUID)
|
||||
}
|
||||
|
||||
// DeleteVolume deletes a Quobyte volume
|
||||
func (client *QuobyteClient) DeleteVolume(UUID string) error {
|
||||
return client.sendRequest(
|
||||
|
@ -182,10 +221,9 @@ func (client *QuobyteClient) SetTenant(tenantName string) (string, error) {
|
|||
return response.TenantID, nil
|
||||
}
|
||||
|
||||
// IsValidUUID Validates given uuid
|
||||
// IsValidUUID Validates the given uuid
|
||||
func IsValidUUID(uuid string) bool {
|
||||
r := regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
|
||||
return r.MatchString(uuid)
|
||||
return UUIDValidator.MatchString(uuid)
|
||||
}
|
||||
|
||||
// ResolveTenantNameToUUID Returns UUID for given name, error if not found.
|
||||
|
|
Loading…
Reference in New Issue