diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 3eda891b8..cb16f5426 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -11,7 +11,7 @@ import ( "github.com/netapp/trident/config" "github.com/spf13/cobra" - k8s "k8s.io/client-go/pkg/api/v1" + k8s "k8s.io/api/core/v1" ) const ( diff --git a/docs/reference/concepts/objects.rst b/docs/reference/concepts/objects.rst index 211ad874b..2fa718180 100644 --- a/docs/reference/concepts/objects.rst +++ b/docs/reference/concepts/objects.rst @@ -171,8 +171,6 @@ A Kubernetes StorageClass object that uses Trident looks like this: These parameters are Trident-specific and tell Trident how to provision volumes for the class. -The storage class parameters are: - ================= ===================== ======== ===================================================== Attribute Type Required Description ================= ===================== ======== ===================================================== @@ -180,7 +178,11 @@ attributes map[string]string no See the attributes section belo requiredStorage map[string]StringList no Map of backend names to lists of storage pools within ================= ===================== ======== ===================================================== -The current attributes and their possible values are: +Storage attributes and their possible values can be classified into two groups: + +1. Storage pool selection attributes: These parameters determine which + Trident-managed storage pools should be utilized to provision volumes of a + given type. ================= ====== ======================================= ========================================================== ============================== ========================================================= Attribute Type Values Offer Request Supported by @@ -221,6 +223,18 @@ use ``tridentctl get backend`` to get the list of backends and their pools. influence one another. If you specify both, Trident will select pools that match all of the ``attributes`` **and** pools that match ``requiredStorage``. + +2. Kubernetes attributes: These attributes have no impact on the selection of + storage pools/backends by Trident during dynamic provisioning. Instead, + these attributes simply supply parameters supported by Kubernetes Persistent + Volumes. + +================= ======= ======================================= ================================================= ======================================================= =================== +Attribute Type Values Description Relevant Drivers Kubernetes Version +================= ======= ======================================= ================================================= ======================================================= =================== +fsType string ext4, ext3, xfs, etc. The file system type for block volumes solidfire-san, ontap-san, eseries-iscsi All +================= ======= ======================================= ================================================= ======================================================= =================== + The Trident installer bundle provides several example storage class definitions for use with Trident in ``sample-input/storage-class-*.yaml``. Deleting a Kubernetes storage class will cause the corresponding Trident storage class diff --git a/frontend/kubernetes/config.go b/frontend/kubernetes/config.go index 8d53a8ae9..6c2209c23 100644 --- a/frontend/kubernetes/config.go +++ b/frontend/kubernetes/config.go @@ -11,12 +11,16 @@ import ( const ( KubernetesSyncPeriod = 60 * time.Second + // Kubernetes-defined storage class parameters + K8sFsType = "fsType" + // Kubernetes-defined annotations // (Based on kubernetes/pkg/controller/volume/persistentvolume/controller.go) AnnClass = "volume.beta.kubernetes.io/storage-class" AnnDynamicallyProvisioned = "pv.kubernetes.io/provisioned-by" AnnStorageProvisioner = "volume.beta.kubernetes.io/storage-provisioner" AnnDefaultStorageClass = "storageclass.kubernetes.io/is-default-class" + AnnMountOptions = "volume.beta.kubernetes.io/mount-options" // Orchestrator-defined annotations AnnOrchestrator = "netapp.io/" + config.OrchestratorName @@ -36,6 +40,6 @@ const ( AnnSplitOnClone = AnnPrefix + "/splitOnClone" // Minimum and maximum supported Kubernetes versions - KubernetesVersionMin = "v1.4.0" - KubernetesVersionMax = "v1.6.0" + KubernetesVersionMin = "v1.5.0" + KubernetesVersionMax = "v1.8.0" ) diff --git a/frontend/kubernetes/plugin.go b/frontend/kubernetes/plugin.go index 0e11e7bf5..f3d2578ad 100644 --- a/frontend/kubernetes/plugin.go +++ b/frontend/kubernetes/plugin.go @@ -9,6 +9,9 @@ import ( log "github.com/Sirupsen/logrus" dvp "github.com/netapp/netappdvp/storage_drivers" + "k8s.io/api/core/v1" + k8s_storage_v1 "k8s.io/api/storage/v1" + k8s_storage_v1beta "k8s.io/api/storage/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" @@ -16,10 +19,6 @@ import ( "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" core_v1 "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/pkg/api" - "k8s.io/client-go/pkg/api/v1" - k8s_storage_v1 "k8s.io/client-go/pkg/apis/storage/v1" - k8s_storage_v1beta "k8s.io/client-go/pkg/apis/storage/v1beta1" "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" @@ -53,9 +52,18 @@ func ValidateKubeVersion(versionInfo *k8s_version.Info) (kubeVersion *k8s_util_v return } +// This object captures relevant fields in the storage class that are needed +// during PV creation. +type StorageClassSummary struct { + Parameters map[string]string + MountOptions []string + PersistentVolumeReclaimPolicy *v1.PersistentVolumeReclaimPolicy +} + type KubernetesPlugin struct { orchestrator core.Orchestrator kubeClient kubernetes.Interface + getNamespacedKubeClient func(*rest.Config, string) (k8s_client.Interface, error) kubeConfig rest.Config eventRecorder record.EventRecorder claimController cache.Controller @@ -71,6 +79,7 @@ type KubernetesPlugin struct { pendingClaimMatchMap map[string]*v1.PersistentVolume kubernetesVersion *k8s_version.Info defaultStorageClasses map[string]bool + storageClassCache map[string]*StorageClassSummary } func NewPlugin(o core.Orchestrator, apiServerIP, kubeConfigPath string) (*KubernetesPlugin, error) { @@ -98,6 +107,7 @@ func newKubernetesPlugin(orchestrator core.Orchestrator, kubeConfig *rest.Config ret := &KubernetesPlugin{ orchestrator: orchestrator, kubeClient: kubeClient, + getNamespacedKubeClient: k8s_client.NewKubeClient, kubeConfig: *kubeConfig, claimControllerStopChan: make(chan struct{}), volumeControllerStopChan: make(chan struct{}), @@ -105,6 +115,7 @@ func newKubernetesPlugin(orchestrator core.Orchestrator, kubeConfig *rest.Config mutex: &sync.Mutex{}, pendingClaimMatchMap: make(map[string]*v1.PersistentVolume), defaultStorageClasses: make(map[string]bool, 1), + storageClassCache: make(map[string]*StorageClassSummary), } ret.kubernetesVersion, err = kubeClient.Discovery().ServerVersion() @@ -141,7 +152,7 @@ func newKubernetesPlugin(orchestrator core.Orchestrator, kubeConfig *rest.Config &core_v1.EventSinkImpl{ Interface: kubeClient.Core().Events(""), }) - ret.eventRecorder = broadcaster.NewRecorder(api.Scheme, + ret.eventRecorder = broadcaster.NewRecorder(runtime.NewScheme(), v1.EventSource{Component: AnnOrchestrator}) // Setting up a watch for PVCs @@ -600,9 +611,10 @@ func (p *KubernetesPlugin) createVolumeAndPV(uniqueName string, claim *v1.PersistentVolumeClaim, ) (pv *v1.PersistentVolume, err error) { var ( - nfsSource *v1.NFSVolumeSource - iscsiSource *v1.ISCSIVolumeSource - vol *storage.VolumeExternal + nfsSource *v1.NFSVolumeSource + iscsiSource *v1.ISCSIVolumeSource + vol *storage.VolumeExternal + storageClassParams map[string]string ) defer func() { @@ -627,6 +639,10 @@ func (p *KubernetesPlugin) createVolumeAndPV(uniqueName string, size, _ := claim.Spec.Resources.Requests[v1.ResourceStorage] accessModes := claim.Spec.AccessModes annotations := claim.Annotations + storageClass := GetPersistentVolumeClaimClass(claim) + if storageClassSummary, found := p.storageClassCache[storageClass]; found { + storageClassParams = storageClassSummary.Parameters + } // TODO: A quick way to support v1 storage classes before changing unit tests if _, found := annotations[AnnClass]; !found { @@ -636,12 +652,19 @@ func (p *KubernetesPlugin) createVolumeAndPV(uniqueName string, annotations[AnnClass] = GetPersistentVolumeClaimClass(claim) } - k8sClient, newKubeClientErr := k8s_client.NewKubeClient(&p.kubeConfig, claim.Namespace) - if newKubeClientErr != nil { + // Set the file system type based on the value in the storage class + if _, found := annotations[AnnFileSystem]; !found && storageClassParams != nil { + if fsType, found := storageClassParams[K8sFsType]; found { + annotations[AnnFileSystem] = fsType + } + } + + k8sClient, err := p.getNamespacedKubeClient(&p.kubeConfig, claim.Namespace) + if err != nil { log.WithFields(log.Fields{ "claim.Namespace": claim.Namespace, }).Warnf("Kubernetes frontend couldn't create a client to namespace: %v error: %v", - claim.Namespace, newKubeClientErr.Error()) + claim.Namespace, err.Error()) } // Create the volume configuration object @@ -722,11 +745,22 @@ func (p *KubernetesPlugin) createVolumeAndPV(uniqueName string, PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete, }, } + kubeVersion, _ := ValidateKubeVersion(p.kubernetesVersion) switch { + //TODO: Set StorageClassName when we create the PV once the support for + // k8s 1.5 is dropped. + case kubeVersion.AtLeast(k8s_util_version.MustParseSemantic("v1.8.0")): + pv.Spec.StorageClassName = GetPersistentVolumeClaimClass(claim) + // Apply Storage Class mount options and reclaim policy + pv.Spec.MountOptions = p.storageClassCache[storageClass].MountOptions + pv.Spec.PersistentVolumeReclaimPolicy = + *p.storageClassCache[storageClass].PersistentVolumeReclaimPolicy case kubeVersion.AtLeast(k8s_util_version.MustParseSemantic("v1.6.0")): pv.Spec.StorageClassName = GetPersistentVolumeClaimClass(claim) } + + // PVC annotation takes precedence over the storage class field if getClaimReclaimPolicy(claim) == string(v1.PersistentVolumeReclaimRetain) { // Extra flexibility in our implementation. @@ -1087,11 +1121,16 @@ func (p *KubernetesPlugin) processAddedClass(class *k8s_storage_v1.StorageClass) scConfig := new(storage_class.Config) scConfig.Name = class.Name scConfig.Attributes = make(map[string]storage_attribute.Request) + k8sStorageClassParams := make(map[string]string) // Populate storage class config attributes and backend storage pools for k, v := range class.Parameters { - if k == storage_attribute.BackendStoragePools { - // format: backendStoragePools: "backend1:pool1,pool2;backend2:pool1" + switch k { + case K8sFsType: + // Process Kubernetes-defined storage class parameters + k8sStorageClassParams[k] = v + case storage_attribute.BackendStoragePools: + // format: backendStoragePools: "backend1:pool1,pool2;backend2:pool1" backendPools, err := storage_attribute.CreateBackendStoragePoolsMapFromEncodedString(v) if err != nil { log.WithFields(log.Fields{ @@ -1102,21 +1141,34 @@ func (p *KubernetesPlugin) processAddedClass(class *k8s_storage_v1.StorageClass) storage_attribute.BackendStoragePools, err) } scConfig.BackendStoragePools = backendPools - continue - } - // format: attribute: "value" - req, err := storage_attribute.CreateAttributeRequestFromAttributeValue(k, v) - if err != nil { - log.WithFields(log.Fields{ - "storageClass": class.Name, - "storageClass_provisioner": class.Provisioner, - "storageClass_parameters": class.Parameters, - }).Error("Kubernetes frontend couldn't process the encoded storage class attribute: ", err) - return + + default: + // format: attribute: "value" + req, err := storage_attribute.CreateAttributeRequestFromAttributeValue(k, v) + if err != nil { + log.WithFields(log.Fields{ + "storageClass": class.Name, + "storageClass_provisioner": class.Provisioner, + "storageClass_parameters": class.Parameters, + }).Error("Kubernetes frontend couldn't process the encoded storage class attribute: ", err) + return + } + scConfig.Attributes[k] = req } - scConfig.Attributes[k] = req } + // Update Kubernetes-defined storage class parameters maintained by the + // frontend. Note that these parameters are only processed by the frontend + // and not by Trident core. + p.mutex.Lock() + storageClassSummary := &StorageClassSummary{ + Parameters: k8sStorageClassParams, + MountOptions: class.MountOptions, + PersistentVolumeReclaimPolicy: class.ReclaimPolicy, + } + p.storageClassCache[class.Name] = storageClassSummary + p.mutex.Unlock() + // Add the storage class sc, err := p.orchestrator.AddStorageClass(scConfig) if err != nil { @@ -1233,7 +1285,7 @@ func (p *KubernetesPlugin) getDefaultStorageClasses() string { // requested, it returns "". func GetPersistentVolumeClaimClass(claim *v1.PersistentVolumeClaim) string { // Use beta annotation first - if class, found := claim.Annotations[api.BetaStorageClassAnnotation]; found { + if class, found := claim.Annotations[AnnClass]; found { return class } diff --git a/frontend/kubernetes/plugin_test.go b/frontend/kubernetes/plugin_test.go index e83bea7ed..eae4665a7 100644 --- a/frontend/kubernetes/plugin_test.go +++ b/frontend/kubernetes/plugin_test.go @@ -11,18 +11,18 @@ import ( log "github.com/Sirupsen/logrus" + "k8s.io/api/core/v1" + k8s_storage_v1 "k8s.io/api/storage/v1" + k8s_storage_v1beta "k8s.io/api/storage/v1beta1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/diff" k8s_version "k8s.io/apimachinery/pkg/version" "k8s.io/client-go/kubernetes/fake" core_v1 "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/pkg/api" - "k8s.io/client-go/pkg/api/v1" - k8s_storage_v1 "k8s.io/client-go/pkg/apis/storage/v1" - k8s_storage_v1beta "k8s.io/client-go/pkg/apis/storage/v1beta1" "k8s.io/client-go/tools/cache" framework "k8s.io/client-go/tools/cache/testing" "k8s.io/client-go/tools/record" @@ -216,6 +216,7 @@ func newTestPlugin( mutex: &sync.Mutex{}, pendingClaimMatchMap: make(map[string]*v1.PersistentVolume), defaultStorageClasses: make(map[string]bool, 1), + storageClassCache: make(map[string]*StorageClassSummary), } ret.kubernetesVersion = kubeVersion ret.claimSource = claimSource @@ -272,12 +273,13 @@ func newTestPlugin( ) } ret.kubeClient = client + ret.getNamespacedKubeClient = k8s_client.NewFakeKubeClientBasic broadcaster := record.NewBroadcaster() broadcaster.StartRecordingToSink( &core_v1.EventSinkImpl{ Interface: client.Core().Events(""), }) - ret.eventRecorder = broadcaster.NewRecorder(api.Scheme, + ret.eventRecorder = broadcaster.NewRecorder(runtime.NewScheme(), v1.EventSource{Component: AnnOrchestrator}) // Note that at the moment we can only actually support NFS here; the // iSCSI backends all trigger interactions with a real backend to map diff --git a/frontend/kubernetes/reactor_test.go b/frontend/kubernetes/reactor_test.go index e6c4f1e32..f84f8624a 100644 --- a/frontend/kubernetes/reactor_test.go +++ b/frontend/kubernetes/reactor_test.go @@ -10,11 +10,11 @@ import ( "time" log "github.com/Sirupsen/logrus" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/client-go/kubernetes/fake" - "k8s.io/client-go/pkg/api/v1" k8s_testing "k8s.io/client-go/testing" framework "k8s.io/client-go/tools/cache/testing" ) diff --git a/frontend/kubernetes/volumes.go b/frontend/kubernetes/volumes.go index 41e46cec4..4674a6fc7 100644 --- a/frontend/kubernetes/volumes.go +++ b/frontend/kubernetes/volumes.go @@ -7,8 +7,8 @@ import ( "strings" log "github.com/Sirupsen/logrus" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/client-go/pkg/api/v1" "github.com/netapp/trident/config" "github.com/netapp/trident/k8s_client" diff --git a/glide.lock b/glide.lock index 150e1e70b..6f1878a0c 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: efc893e8c983268e52ccb4bc18b3774c6bb3fea15544a80f06c4e3be340041b0 -updated: 2017-11-30T14:48:37.036685649-05:00 +hash: 21d11c7ae723deb1194c8a036dcceb31d09a88c841a9c9fb41f626dc273e4f83 +updated: 2017-12-13T14:19:43.847486918-05:00 imports: - name: github.com/beorn7/perks version: 3ac7bf7a47d159a033b107610db8a1b6575507a4 @@ -28,14 +28,9 @@ imports: - journal - util - name: github.com/davecgh/go-spew - version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d + version: 782f4967f2dc4564575ca782fe2d04090b5faca8 subpackages: - spew -- name: github.com/docker/distribution - version: cd27f179f2c10c5d300e6d09025b538c475b0d51 - subpackages: - - digest - - reference - name: github.com/docker/go-connections version: 3ede32e2033de7505e6500d6c868c2b9ed9f169d subpackages: @@ -55,14 +50,10 @@ imports: version: dcef7f55730566d41eae5db10e7d6981829720f6 - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee -- name: github.com/go-openapi/analysis - version: b44dc874b601d9e4e2f6e19140e794ba24bead3b - name: github.com/go-openapi/jsonpointer version: 46af16f9f7b149af66e5d1bd010e3574dc06de98 - name: github.com/go-openapi/jsonreference version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272 -- name: github.com/go-openapi/loads - version: 18441dfa706d924a39a030ee2c3b1d8d81917b38 - name: github.com/go-openapi/spec version: 6aced65f8501fe1217321abf0749d354824ba2ff - name: github.com/go-openapi/swag @@ -83,12 +74,28 @@ imports: subpackages: - jsonpb - proto + - ptypes + - ptypes/any + - ptypes/duration + - ptypes/timestamp +- name: github.com/google/btree + version: 7d79101e329e5a3adf994758c578dab82b90c017 - name: github.com/google/gofuzz version: 44d81051d367757e1c7c6a5a86423ece9afcf63c +- name: github.com/googleapis/gnostic + version: 0c5108395e2debce0d731cf0287ddf7242066aba + subpackages: + - OpenAPIv2 + - compiler + - extensions - name: github.com/gorilla/context version: 215affda49addc4c8ef7e2534915df2c8c35c6cd - name: github.com/gorilla/mux version: 8096f47503459bcc74d1f4c487b7e6e42e5746b5 +- name: github.com/gregjones/httpcache + version: 787624de3eb7bd915c329cba748687a3b22666a6 + subpackages: + - diskcache - name: github.com/grpc-ecosystem/go-grpc-prometheus version: 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 - name: github.com/grpc-ecosystem/grpc-gateway @@ -107,6 +114,8 @@ imports: version: 6633656539c1639d9d78127b7d47c622b5d7b6dc - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 +- name: github.com/json-iterator/go + version: 36b14963da70d11297d313183d7e6388c8510e1e - name: github.com/juju/ratelimit version: 5b9ff866471762aa2ab2dced63c9fb6f53921342 - name: github.com/mailru/easyjson @@ -138,6 +147,8 @@ imports: version: a7a4c189eb47ed33ce7b35f2880070a0c82a67d4 - name: github.com/pborman/uuid version: ca53cad383cad2479bbba7f7a1a05797ec1386e4 +- name: github.com/peterbourgon/diskv + version: 5f041e8faa004a95c88a202771f4cc3e991971e6 - name: github.com/prometheus/client_golang version: c5b7fccd204277076155f10851dad72b76a49317 subpackages: @@ -175,7 +186,7 @@ imports: subpackages: - ssh/terminal - name: golang.org/x/net - version: f2499483f923065a842d38eb4c7f1927e6fc6e6d + version: 1c05540f6879653db88113bc4a2b70aec4bd491f subpackages: - context - http2 @@ -186,14 +197,15 @@ imports: - proxy - trace - name: golang.org/x/sys - version: 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9 + version: 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce subpackages: - unix - windows - name: golang.org/x/text - version: 2910a502d2bf9e43193af9d68ca516529614eed3 + version: b19bf474d317b857955b12035d2c5acb57ce8b01 subpackages: - cases + - internal - internal/tag - language - runes @@ -218,16 +230,41 @@ imports: version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 - name: gopkg.in/yaml.v2 version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 +- name: k8s.io/api + version: 6c6dac0277229b9e9578c5ca3f74a4345d35cdc2 + subpackages: + - admissionregistration/v1alpha1 + - apps/v1beta1 + - apps/v1beta2 + - authentication/v1 + - authentication/v1beta1 + - authorization/v1 + - authorization/v1beta1 + - autoscaling/v1 + - autoscaling/v2beta1 + - batch/v1 + - batch/v1beta1 + - batch/v2alpha1 + - certificates/v1beta1 + - core/v1 + - extensions/v1beta1 + - networking/v1 + - policy/v1beta1 + - rbac/v1 + - rbac/v1alpha1 + - rbac/v1beta1 + - scheduling/v1alpha1 + - settings/v1alpha1 + - storage/v1 + - storage/v1beta1 - name: k8s.io/apimachinery - version: 917740426ad66ff818da4809990480bcc0786a77 + version: 019ae5ada31de202164b118aee88ee2d14075c31 subpackages: - pkg/api/equality - pkg/api/errors - pkg/api/meta - pkg/api/resource - - pkg/apimachinery - - pkg/apimachinery/announced - - pkg/apimachinery/registered + - pkg/apis/meta/internalversion - pkg/apis/meta/v1 - pkg/apis/meta/v1/unstructured - pkg/apis/meta/v1alpha1 @@ -236,7 +273,6 @@ imports: - pkg/conversion/unstructured - pkg/fields - pkg/labels - - pkg/openapi - pkg/runtime - pkg/runtime/schema - pkg/runtime/serializer @@ -256,7 +292,6 @@ imports: - pkg/util/json - pkg/util/mergepatch - pkg/util/net - - pkg/util/rand - pkg/util/runtime - pkg/util/sets - pkg/util/strategicpatch @@ -269,7 +304,7 @@ imports: - third_party/forked/golang/json - third_party/forked/golang/reflect - name: k8s.io/client-go - version: 2a227f04f328fe506bd562f50b4d2a175fce80c5 + version: 2ae454230481a7cb5544325e12ad7658ecccd19b subpackages: - discovery - discovery/fake @@ -280,6 +315,8 @@ imports: - kubernetes/typed/admissionregistration/v1alpha1/fake - kubernetes/typed/apps/v1beta1 - kubernetes/typed/apps/v1beta1/fake + - kubernetes/typed/apps/v1beta2 + - kubernetes/typed/apps/v1beta2/fake - kubernetes/typed/authentication/v1 - kubernetes/typed/authentication/v1/fake - kubernetes/typed/authentication/v1beta1 @@ -290,10 +327,12 @@ imports: - kubernetes/typed/authorization/v1beta1/fake - kubernetes/typed/autoscaling/v1 - kubernetes/typed/autoscaling/v1/fake - - kubernetes/typed/autoscaling/v2alpha1 - - kubernetes/typed/autoscaling/v2alpha1/fake + - kubernetes/typed/autoscaling/v2beta1 + - kubernetes/typed/autoscaling/v2beta1/fake - kubernetes/typed/batch/v1 - kubernetes/typed/batch/v1/fake + - kubernetes/typed/batch/v1beta1 + - kubernetes/typed/batch/v1beta1/fake - kubernetes/typed/batch/v2alpha1 - kubernetes/typed/batch/v2alpha1/fake - kubernetes/typed/certificates/v1beta1 @@ -306,53 +345,21 @@ imports: - kubernetes/typed/networking/v1/fake - kubernetes/typed/policy/v1beta1 - kubernetes/typed/policy/v1beta1/fake + - kubernetes/typed/rbac/v1 + - kubernetes/typed/rbac/v1/fake - kubernetes/typed/rbac/v1alpha1 - kubernetes/typed/rbac/v1alpha1/fake - kubernetes/typed/rbac/v1beta1 - kubernetes/typed/rbac/v1beta1/fake + - kubernetes/typed/scheduling/v1alpha1 + - kubernetes/typed/scheduling/v1alpha1/fake - kubernetes/typed/settings/v1alpha1 - kubernetes/typed/settings/v1alpha1/fake - kubernetes/typed/storage/v1 - kubernetes/typed/storage/v1/fake - kubernetes/typed/storage/v1beta1 - kubernetes/typed/storage/v1beta1/fake - - pkg/api - - pkg/api/v1 - - pkg/api/v1/ref - - pkg/apis/admissionregistration - - pkg/apis/admissionregistration/v1alpha1 - - pkg/apis/apps - - pkg/apis/apps/v1beta1 - - pkg/apis/authentication - - pkg/apis/authentication/v1 - - pkg/apis/authentication/v1beta1 - - pkg/apis/authorization - - pkg/apis/authorization/v1 - - pkg/apis/authorization/v1beta1 - - pkg/apis/autoscaling - - pkg/apis/autoscaling/v1 - - pkg/apis/autoscaling/v2alpha1 - - pkg/apis/batch - - pkg/apis/batch/v1 - - pkg/apis/batch/v2alpha1 - - pkg/apis/certificates - - pkg/apis/certificates/v1beta1 - - pkg/apis/extensions - - pkg/apis/extensions/v1beta1 - - pkg/apis/networking - - pkg/apis/networking/v1 - - pkg/apis/policy - - pkg/apis/policy/v1beta1 - - pkg/apis/rbac - - pkg/apis/rbac/v1alpha1 - - pkg/apis/rbac/v1beta1 - - pkg/apis/settings - - pkg/apis/settings/v1alpha1 - pkg/apis/storage - - pkg/apis/storage/v1 - - pkg/apis/storage/v1beta1 - - pkg/util - - pkg/util/parsers - pkg/version - rest - rest/watch @@ -365,10 +372,16 @@ imports: - tools/clientcmd/api/latest - tools/clientcmd/api/v1 - tools/metrics + - tools/pager - tools/record + - tools/reference - transport - util/cert - util/flowcontrol - util/homedir - util/integer +- name: k8s.io/kube-openapi + version: 868f2f29720b192240e18284659231b440f9cda5 + subpackages: + - pkg/common testImports: [] diff --git a/glide.yaml b/glide.yaml index 9fd6c2587..2988aeab2 100644 --- a/glide.yaml +++ b/glide.yaml @@ -35,24 +35,25 @@ import: - package: github.com/spf13/cobra version: f62e98d28ab7ad31d707ba837a966378465c7b57 - package: golang.org/x/net - version: f2499483f923065a842d38eb4c7f1927e6fc6e6d + version: 1c05540f6879653db88113bc4a2b70aec4bd491f subpackages: - context - package: google.golang.org/grpc version: v1.0.4 +- package: k8s.io/api + version: 6c6dac0277229b9e9578c5ca3f74a4345d35cdc2 + subpackages: + - core/v1 + - extensions/v1beta1 + - storage/v1 + - storage/v1beta1 - package: k8s.io/client-go - version: 2a227f04f328fe506bd562f50b4d2a175fce80c5 + version: 2ae454230481a7cb5544325e12ad7658ecccd19b subpackages: - kubernetes - kubernetes/fake - kubernetes/typed/core/v1 - - pkg/api - - pkg/api/v1 - - pkg/apis/extensions - - pkg/apis/extensions/v1beta1 - pkg/apis/storage - - pkg/apis/storage/v1 - - pkg/apis/storage/v1beta1 - rest - testing - tools/cache @@ -60,7 +61,7 @@ import: - tools/cache/testing - tools/record - package: k8s.io/apimachinery - version: 917740426ad66ff818da4809990480bcc0786a77 + version: 019ae5ada31de202164b118aee88ee2d14075c31 subpackages: - pkg/api/errors - pkg/api/resource diff --git a/k8s_client/k8s_client.go b/k8s_client/k8s_client.go index a77772370..3ceb2a764 100644 --- a/k8s_client/k8s_client.go +++ b/k8s_client/k8s_client.go @@ -8,13 +8,13 @@ import ( "time" log "github.com/Sirupsen/logrus" + "k8s.io/api/core/v1" + "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/version" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/pkg/api/v1" - "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/client-go/rest" ) @@ -54,7 +54,7 @@ type KubeClient struct { versionInfo *version.Info } -func NewKubeClient(config *rest.Config, namespace string) (*KubeClient, error) { +func NewKubeClient(config *rest.Config, namespace string) (Interface, error) { var versionInfo *version.Info if namespace == "" { return nil, fmt.Errorf("An empty namespace is not acceptable!") diff --git a/k8s_client/k8s_client_fake.go b/k8s_client/k8s_client_fake.go index a20414585..195dcd041 100644 --- a/k8s_client/k8s_client_fake.go +++ b/k8s_client/k8s_client_fake.go @@ -6,12 +6,13 @@ import ( "fmt" "sort" + "k8s.io/api/core/v1" + "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/version" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/pkg/api/v1" - "k8s.io/client-go/pkg/apis/extensions/v1beta1" + "k8s.io/client-go/rest" ) type FakeKubeClient struct { @@ -21,6 +22,19 @@ type FakeKubeClient struct { failMatrix map[string]bool } +func NewFakeKubeClientBasic(config *rest.Config, namespace string) (Interface, error) { + return &FakeKubeClient{ + version: &version.Info{ + Major: "1", + Minor: "8", + GitVersion: "v1.8.0", + }, + Deployments: make(map[string]*v1beta1.Deployment, 0), + PVCs: make(map[string]*v1.PersistentVolumeClaim, 0), + failMatrix: make(map[string]bool, 0), + }, nil +} + func NewFakeKubeClient(failMatrix map[string]bool, versionMajor, versionMinor string) *FakeKubeClient { return &FakeKubeClient{ version: &version.Info{ diff --git a/launcher/launcher.go b/launcher/launcher.go index 55af82bfc..43c1896b2 100644 --- a/launcher/launcher.go +++ b/launcher/launcher.go @@ -14,12 +14,12 @@ import ( log "github.com/Sirupsen/logrus" "github.com/netapp/trident/k8s_client" + "k8s.io/api/core/v1" + "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apimachinery/pkg/version" - "k8s.io/client-go/pkg/api/v1" - "k8s.io/client-go/pkg/apis/extensions/v1beta1" k8srest "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" diff --git a/launcher/launcher_test.go b/launcher/launcher_test.go index c7eb81d86..69184c30c 100644 --- a/launcher/launcher_test.go +++ b/launcher/launcher_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" + "k8s.io/api/core/v1" + "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/version" - "k8s.io/client-go/pkg/api/v1" - "k8s.io/client-go/pkg/apis/extensions/v1beta1" tridentrest "github.com/netapp/trident/frontend/rest" "github.com/netapp/trident/k8s_client" diff --git a/trident-installer/sample-input/storage-class-ontap-gold.yaml b/trident-installer/sample-input/storage-class-ontapnas-gold.yaml similarity index 100% rename from trident-installer/sample-input/storage-class-ontap-gold.yaml rename to trident-installer/sample-input/storage-class-ontapnas-gold.yaml diff --git a/trident-installer/sample-input/storage-class-ontapnas-k8s1.8-mountoptions.yaml b/trident-installer/sample-input/storage-class-ontapnas-k8s1.8-mountoptions.yaml new file mode 100644 index 000000000..2ede87a33 --- /dev/null +++ b/trident-installer/sample-input/storage-class-ontapnas-k8s1.8-mountoptions.yaml @@ -0,0 +1,8 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: ontapnasudp +provisioner: netapp.io/trident +mountOptions: ["rw", "nfsvers=3", "proto=udp"] +parameters: + backendType: "ontap-nas" diff --git a/trident-installer/sample-input/storage-class-solidfire-bronze.yaml b/trident-installer/sample-input/storage-class-solidfire-bronze.yaml index 5cec7bbdf..8b635f41c 100644 --- a/trident-installer/sample-input/storage-class-solidfire-bronze.yaml +++ b/trident-installer/sample-input/storage-class-solidfire-bronze.yaml @@ -6,4 +6,5 @@ provisioner: netapp.io/trident parameters: backendType: "solidfire-san" IOPS: "1500" + fsType: "ext4"