2016-10-17 14:50:00 +00:00
/ *
2017-07-13 11:55:32 +00:00
Copyright 2017 The Kubernetes Authors .
2016-10-17 14:50:00 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package azure_dd
import (
"fmt"
"strings"
2017-06-22 18:24:23 +00:00
"k8s.io/api/core/v1"
2017-01-25 13:13:07 +00:00
"k8s.io/apimachinery/pkg/api/resource"
2017-01-17 03:38:19 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2016-10-17 14:50:00 +00:00
"k8s.io/kubernetes/pkg/volume"
)
2017-07-13 11:55:32 +00:00
type azureDiskProvisioner struct {
plugin * azureDataDiskPlugin
options volume . VolumeOptions
}
2016-10-17 14:50:00 +00:00
type azureDiskDeleter struct {
2017-07-13 11:55:32 +00:00
* dataDisk
spec * volume . Spec
plugin * azureDataDiskPlugin
2016-10-17 14:50:00 +00:00
}
2017-07-13 11:55:32 +00:00
var _ volume . Provisioner = & azureDiskProvisioner { }
var _ volume . Deleter = & azureDiskDeleter { }
2016-10-17 14:50:00 +00:00
2017-07-13 11:55:32 +00:00
func ( d * azureDiskDeleter ) GetPath ( ) string {
return getPath ( d . podUID , d . dataDisk . diskName , d . plugin . host )
2016-10-17 14:50:00 +00:00
}
2017-07-13 11:55:32 +00:00
func ( d * azureDiskDeleter ) Delete ( ) error {
volumeSource , err := getVolumeSource ( d . spec )
if err != nil {
return err
2016-10-17 14:50:00 +00:00
}
2017-07-13 11:55:32 +00:00
diskController , err := getDiskController ( d . plugin . host )
2016-10-17 14:50:00 +00:00
if err != nil {
2017-07-13 11:55:32 +00:00
return err
2016-10-17 14:50:00 +00:00
}
2017-07-13 11:55:32 +00:00
wasStandAlone := ( * volumeSource . Kind != v1 . AzureSharedBlobDisk )
managed := ( * volumeSource . Kind == v1 . AzureManagedDisk )
2016-10-17 14:50:00 +00:00
2017-07-13 11:55:32 +00:00
if managed {
return diskController . DeleteManagedDisk ( volumeSource . DataDiskURI )
}
2016-10-17 14:50:00 +00:00
2017-07-13 11:55:32 +00:00
return diskController . DeleteBlobDisk ( volumeSource . DataDiskURI , wasStandAlone )
2016-10-17 14:50:00 +00:00
}
2017-07-13 11:55:32 +00:00
func ( p * azureDiskProvisioner ) Provision ( ) ( * v1 . PersistentVolume , error ) {
if ! volume . AccessModesContainedInAll ( p . plugin . GetAccessModes ( ) , p . options . PVC . Spec . AccessModes ) {
return nil , fmt . Errorf ( "invalid AccessModes %v: only AccessModes %v are supported" , p . options . PVC . Spec . AccessModes , p . plugin . GetAccessModes ( ) )
}
supportedModes := p . plugin . GetAccessModes ( )
2016-10-17 14:50:00 +00:00
2017-07-13 11:55:32 +00:00
// perform static validation first
if p . options . PVC . Spec . Selector != nil {
return nil , fmt . Errorf ( "azureDisk - claim.Spec.Selector is not supported for dynamic provisioning on Azure disk" )
}
2016-10-17 14:50:00 +00:00
2017-07-13 11:55:32 +00:00
if len ( p . options . PVC . Spec . AccessModes ) > 1 {
return nil , fmt . Errorf ( "AzureDisk - multiple access modes are not supported on AzureDisk plugin" )
2017-06-09 21:59:08 +00:00
}
2017-07-13 11:55:32 +00:00
if len ( p . options . PVC . Spec . AccessModes ) == 1 {
if p . options . PVC . Spec . AccessModes [ 0 ] != supportedModes [ 0 ] {
return nil , fmt . Errorf ( "AzureDisk - mode %s is not supporetd by AzureDisk plugin supported mode is %s" , p . options . PVC . Spec . AccessModes [ 0 ] , supportedModes )
}
}
2016-10-17 14:50:00 +00:00
2017-07-13 11:55:32 +00:00
var (
location , account string
storageAccountType , fsType string
cachingMode v1 . AzureDataDiskCachingMode
strKind string
err error
)
2017-01-15 13:53:52 +00:00
// maxLength = 79 - (4 for ".vhd") = 75
2017-07-13 11:55:32 +00:00
name := volume . GenerateVolumeName ( p . options . ClusterName , p . options . PVName , 75 )
capacity := p . options . PVC . Spec . Resources . Requests [ v1 . ResourceName ( v1 . ResourceStorage ) ]
2016-10-17 14:50:00 +00:00
requestBytes := capacity . Value ( )
requestGB := int ( volume . RoundUpSize ( requestBytes , 1024 * 1024 * 1024 ) )
2017-07-13 11:55:32 +00:00
for k , v := range p . options . Parameters {
2016-10-17 14:50:00 +00:00
switch strings . ToLower ( k ) {
case "skuname" :
2017-07-13 11:55:32 +00:00
storageAccountType = v
2016-10-17 14:50:00 +00:00
case "location" :
location = v
case "storageaccount" :
account = v
2017-07-13 11:55:32 +00:00
case "storageaccounttype" :
storageAccountType = v
case "kind" :
strKind = v
case "cachingmode" :
cachingMode = v1 . AzureDataDiskCachingMode ( v )
case "fstype" :
fsType = strings . ToLower ( v )
2016-10-17 14:50:00 +00:00
default :
2017-07-13 11:55:32 +00:00
return nil , fmt . Errorf ( "AzureDisk - invalid option %s in storage class" , k )
2016-10-17 14:50:00 +00:00
}
}
2017-07-13 11:55:32 +00:00
// normalize values
fsType = normalizeFsType ( fsType )
skuName , err := normalizeStorageAccountType ( storageAccountType )
if err != nil {
return nil , err
}
kind , err := normalizeKind ( strFirstLetterToUpper ( strKind ) )
if err != nil {
return nil , err
2016-10-17 14:50:00 +00:00
}
2017-07-13 11:55:32 +00:00
if cachingMode , err = normalizeCachingMode ( cachingMode ) ; err != nil {
return nil , err
}
diskController , err := getDiskController ( p . plugin . host )
2016-10-17 14:50:00 +00:00
if err != nil {
return nil , err
}
2017-07-13 11:55:32 +00:00
// create disk
diskURI := ""
if kind == v1 . AzureManagedDisk {
diskURI , err = diskController . CreateManagedDisk ( name , skuName , requestGB , * ( p . options . CloudTags ) )
if err != nil {
return nil , err
}
} else {
forceStandAlone := ( kind == v1 . AzureDedicatedBlobDisk )
if kind == v1 . AzureDedicatedBlobDisk {
if location != "" && account != "" {
// use dedicated kind (by default) for compatibility
_ , diskURI , _ , err = diskController . CreateVolume ( name , account , skuName , location , requestGB )
if err != nil {
return nil , err
}
} else {
if location != "" || account != "" {
return nil , fmt . Errorf ( "AzureDisk - location(%s) and account(%s) must be both empty or specified for dedicated kind, only one value specified is not allowed" ,
location , account )
}
diskURI , err = diskController . CreateBlobDisk ( name , skuName , requestGB , forceStandAlone )
if err != nil {
return nil , err
}
}
} else {
diskURI , err = diskController . CreateBlobDisk ( name , skuName , requestGB , forceStandAlone )
if err != nil {
return nil , err
}
}
}
2016-11-18 20:58:56 +00:00
pv := & v1 . PersistentVolume {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2017-07-13 11:55:32 +00:00
Name : p . options . PVName ,
2016-10-17 14:50:00 +00:00
Labels : map [ string ] string { } ,
Annotations : map [ string ] string {
2017-07-13 11:55:32 +00:00
"volumehelper.VolumeDynamicallyCreatedByKey" : "azure-disk-dynamic-provisioner" ,
2016-10-17 14:50:00 +00:00
} ,
} ,
2016-11-18 20:58:56 +00:00
Spec : v1 . PersistentVolumeSpec {
2017-07-13 11:55:32 +00:00
PersistentVolumeReclaimPolicy : p . options . PersistentVolumeReclaimPolicy ,
AccessModes : supportedModes ,
2016-11-18 20:58:56 +00:00
Capacity : v1 . ResourceList {
2017-07-13 11:55:32 +00:00
v1 . ResourceName ( v1 . ResourceStorage ) : resource . MustParse ( fmt . Sprintf ( "%dGi" , requestGB ) ) ,
2016-10-17 14:50:00 +00:00
} ,
2016-11-18 20:58:56 +00:00
PersistentVolumeSource : v1 . PersistentVolumeSource {
AzureDisk : & v1 . AzureDiskVolumeSource {
2017-07-13 11:55:32 +00:00
CachingMode : & cachingMode ,
DiskName : name ,
DataDiskURI : diskURI ,
Kind : & kind ,
FSType : & fsType ,
2016-10-17 14:50:00 +00:00
} ,
} ,
} ,
}
return pv , nil
}