mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #68925 from casusbelli/fix_65312
Adding Quobyte Tenant to QuobyteVolumeSource to enable deletion of persistent volumes
This commit is contained in:
		
							
								
								
									
										4
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -3013,8 +3013,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",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								api/openapi-spec/swagger.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								api/openapi-spec/swagger.json
									
									
									
										generated
									
									
									
								
							@@ -86210,6 +86210,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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								pkg/apis/core/v1/zz_generated.conversion.go
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								pkg/apis/core/v1/zz_generated.conversion.go
									
									
									
										generated
									
									
									
								
							@@ -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",
 | 
			
		||||
 
 | 
			
		||||
@@ -330,6 +330,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,
 | 
			
		||||
@@ -428,6 +429,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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1645
									
								
								staging/src/k8s.io/api/core/v1/generated.pb.go
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1645
									
								
								staging/src/k8s.io/api/core/v1/generated.pb.go
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -3422,6 +3422,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 {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								vendor/github.com/quobyte/api/quobyte.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/quobyte/api/quobyte.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -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)
 | 
			
		||||
	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.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user