From d52cdeae7943909b19f47b00109a9a6f811bc939 Mon Sep 17 00:00:00 2001 From: Jiawei Wang Date: Tue, 2 Aug 2022 01:06:17 +0000 Subject: [PATCH] cleanup: Remove storageos volume plugins from k8s codebase --- .../github.com/storageos/go-api/LICENSE | 49 -- cmd/kube-controller-manager/app/plugins.go | 4 - cmd/kubelet/app/plugins.go | 2 - go.mod | 2 - go.sum | 2 - pkg/kubemark/hollow_kubelet.go | 2 - pkg/volume/storageos/doc.go | 19 - pkg/volume/storageos/storageos.go | 762 ------------------ pkg/volume/storageos/storageos_test.go | 384 --------- pkg/volume/storageos/storageos_util.go | 436 ---------- pkg/volume/storageos/storageos_util_test.go | 225 ------ vendor/github.com/storageos/go-api/.gitignore | 24 - vendor/github.com/storageos/go-api/LICENCE | 45 -- vendor/github.com/storageos/go-api/README.md | 5 - vendor/github.com/storageos/go-api/client.go | 612 -------------- vendor/github.com/storageos/go-api/cluster.go | 48 -- vendor/github.com/storageos/go-api/health.go | 91 --- vendor/github.com/storageos/go-api/licence.go | 43 - vendor/github.com/storageos/go-api/logger.go | 62 -- vendor/github.com/storageos/go-api/login.go | 47 -- .../github.com/storageos/go-api/namespace.go | 125 --- .../storageos/go-api/netutil/errors.go | 31 - .../storageos/go-api/netutil/netutil.go | 5 - .../storageos/go-api/netutil/parsers.go | 84 -- .../storageos/go-api/network_diagnostics.go | 35 - vendor/github.com/storageos/go-api/node.go | 110 --- vendor/github.com/storageos/go-api/policy.go | 102 --- vendor/github.com/storageos/go-api/pool.go | 117 --- vendor/github.com/storageos/go-api/rule.go | 141 ---- .../storageos/go-api/serror/error_kind.go | 11 - .../go-api/serror/kind_lookup_map.go | 37 - .../go-api/serror/storageos_error.go | 34 - .../serror/storageoserrorkind_string.go | 16 - .../storageos/go-api/serror/typed_error.go | 64 -- .../storageos/go-api/server_version.go | 28 - .../github.com/storageos/go-api/template.go | 90 --- .../github.com/storageos/go-api/types/auth.go | 14 - .../storageos/go-api/types/capacity_stats.go | 25 - .../storageos/go-api/types/cluster.go | 10 - .../storageos/go-api/types/connectivity.go | 41 - .../storageos/go-api/types/delete_options.go | 24 - .../storageos/go-api/types/deployment.go | 36 - .../storageos/go-api/types/driver_instance.go | 86 -- .../storageos/go-api/types/error_response.go | 13 - .../storageos/go-api/types/events.go | 60 -- .../storageos/go-api/types/health.go | 148 ---- .../storageos/go-api/types/licence.go | 35 - .../storageos/go-api/types/list_options.go | 19 - .../storageos/go-api/types/logger.go | 40 - .../storageos/go-api/types/namespace.go | 59 -- .../github.com/storageos/go-api/types/node.go | 104 --- .../go-api/types/node_update_options.go | 28 - .../storageos/go-api/types/operator.go | 19 - .../storageos/go-api/types/policy.go | 45 -- .../github.com/storageos/go-api/types/pool.go | 39 - .../storageos/go-api/types/pool_options.go | 28 - .../github.com/storageos/go-api/types/rule.go | 125 --- .../storageos/go-api/types/template.go | 53 -- .../go-api/types/template_create_options.go | 51 -- .../github.com/storageos/go-api/types/user.go | 79 -- .../storageos/go-api/types/version.go | 26 - .../storageos/go-api/types/volume.go | 143 ---- .../go-api/types/volume_create_options.go | 36 - .../storageos/go-api/types/volume_stats.go | 8 - .../go-api/types/volume_update_options.go | 34 - vendor/github.com/storageos/go-api/user.go | 118 --- vendor/github.com/storageos/go-api/util.go | 16 - .../github.com/storageos/go-api/validation.go | 76 -- vendor/github.com/storageos/go-api/volume.go | 197 ----- vendor/modules.txt | 7 - 70 files changed, 5736 deletions(-) delete mode 100644 LICENSES/vendor/github.com/storageos/go-api/LICENSE delete mode 100644 pkg/volume/storageos/doc.go delete mode 100644 pkg/volume/storageos/storageos.go delete mode 100644 pkg/volume/storageos/storageos_test.go delete mode 100644 pkg/volume/storageos/storageos_util.go delete mode 100644 pkg/volume/storageos/storageos_util_test.go delete mode 100644 vendor/github.com/storageos/go-api/.gitignore delete mode 100644 vendor/github.com/storageos/go-api/LICENCE delete mode 100644 vendor/github.com/storageos/go-api/README.md delete mode 100644 vendor/github.com/storageos/go-api/client.go delete mode 100644 vendor/github.com/storageos/go-api/cluster.go delete mode 100644 vendor/github.com/storageos/go-api/health.go delete mode 100644 vendor/github.com/storageos/go-api/licence.go delete mode 100644 vendor/github.com/storageos/go-api/logger.go delete mode 100644 vendor/github.com/storageos/go-api/login.go delete mode 100644 vendor/github.com/storageos/go-api/namespace.go delete mode 100644 vendor/github.com/storageos/go-api/netutil/errors.go delete mode 100644 vendor/github.com/storageos/go-api/netutil/netutil.go delete mode 100644 vendor/github.com/storageos/go-api/netutil/parsers.go delete mode 100644 vendor/github.com/storageos/go-api/network_diagnostics.go delete mode 100644 vendor/github.com/storageos/go-api/node.go delete mode 100644 vendor/github.com/storageos/go-api/policy.go delete mode 100644 vendor/github.com/storageos/go-api/pool.go delete mode 100644 vendor/github.com/storageos/go-api/rule.go delete mode 100644 vendor/github.com/storageos/go-api/serror/error_kind.go delete mode 100644 vendor/github.com/storageos/go-api/serror/kind_lookup_map.go delete mode 100644 vendor/github.com/storageos/go-api/serror/storageos_error.go delete mode 100644 vendor/github.com/storageos/go-api/serror/storageoserrorkind_string.go delete mode 100644 vendor/github.com/storageos/go-api/serror/typed_error.go delete mode 100644 vendor/github.com/storageos/go-api/server_version.go delete mode 100644 vendor/github.com/storageos/go-api/template.go delete mode 100644 vendor/github.com/storageos/go-api/types/auth.go delete mode 100644 vendor/github.com/storageos/go-api/types/capacity_stats.go delete mode 100644 vendor/github.com/storageos/go-api/types/cluster.go delete mode 100644 vendor/github.com/storageos/go-api/types/connectivity.go delete mode 100644 vendor/github.com/storageos/go-api/types/delete_options.go delete mode 100644 vendor/github.com/storageos/go-api/types/deployment.go delete mode 100644 vendor/github.com/storageos/go-api/types/driver_instance.go delete mode 100644 vendor/github.com/storageos/go-api/types/error_response.go delete mode 100644 vendor/github.com/storageos/go-api/types/events.go delete mode 100644 vendor/github.com/storageos/go-api/types/health.go delete mode 100644 vendor/github.com/storageos/go-api/types/licence.go delete mode 100644 vendor/github.com/storageos/go-api/types/list_options.go delete mode 100644 vendor/github.com/storageos/go-api/types/logger.go delete mode 100644 vendor/github.com/storageos/go-api/types/namespace.go delete mode 100644 vendor/github.com/storageos/go-api/types/node.go delete mode 100644 vendor/github.com/storageos/go-api/types/node_update_options.go delete mode 100644 vendor/github.com/storageos/go-api/types/operator.go delete mode 100644 vendor/github.com/storageos/go-api/types/policy.go delete mode 100644 vendor/github.com/storageos/go-api/types/pool.go delete mode 100644 vendor/github.com/storageos/go-api/types/pool_options.go delete mode 100644 vendor/github.com/storageos/go-api/types/rule.go delete mode 100644 vendor/github.com/storageos/go-api/types/template.go delete mode 100644 vendor/github.com/storageos/go-api/types/template_create_options.go delete mode 100644 vendor/github.com/storageos/go-api/types/user.go delete mode 100644 vendor/github.com/storageos/go-api/types/version.go delete mode 100644 vendor/github.com/storageos/go-api/types/volume.go delete mode 100644 vendor/github.com/storageos/go-api/types/volume_create_options.go delete mode 100644 vendor/github.com/storageos/go-api/types/volume_stats.go delete mode 100644 vendor/github.com/storageos/go-api/types/volume_update_options.go delete mode 100644 vendor/github.com/storageos/go-api/user.go delete mode 100644 vendor/github.com/storageos/go-api/util.go delete mode 100644 vendor/github.com/storageos/go-api/validation.go delete mode 100644 vendor/github.com/storageos/go-api/volume.go diff --git a/LICENSES/vendor/github.com/storageos/go-api/LICENSE b/LICENSES/vendor/github.com/storageos/go-api/LICENSE deleted file mode 100644 index ea089f663dc..00000000000 --- a/LICENSES/vendor/github.com/storageos/go-api/LICENSE +++ /dev/null @@ -1,49 +0,0 @@ -= vendor/github.com/storageos/go-api licensed under: = - -MIT License - -Copyright (c) 2015-2018 StorageOS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -Copyright (c) 2013-2017, go-dockerclient authors -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -= vendor/github.com/storageos/go-api/LICENCE 10d8703157b5fd9422b1813bae555905 diff --git a/cmd/kube-controller-manager/app/plugins.go b/cmd/kube-controller-manager/app/plugins.go index d9e1b4cd52f..114c4b459cc 100644 --- a/cmd/kube-controller-manager/app/plugins.go +++ b/cmd/kube-controller-manager/app/plugins.go @@ -39,7 +39,6 @@ import ( "k8s.io/kubernetes/pkg/volume/iscsi" "k8s.io/kubernetes/pkg/volume/local" "k8s.io/kubernetes/pkg/volume/nfs" - "k8s.io/kubernetes/pkg/volume/storageos" volumeutil "k8s.io/kubernetes/pkg/volume/util" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -59,7 +58,6 @@ func ProbeAttachableVolumePlugins() ([]volume.VolumePlugin, error) { if err != nil { return allPlugins, err } - allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...) allPlugins = append(allPlugins, iscsi.ProbeVolumePlugins()...) allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...) @@ -82,7 +80,6 @@ func ProbeExpandableVolumePlugins(config persistentvolumeconfig.VolumeConfigurat return allPlugins, err } allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...) - allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...) return allPlugins, nil } @@ -131,7 +128,6 @@ func ProbeControllerVolumePlugins(cloud cloudprovider.Interface, config persiste } allPlugins = append(allPlugins, local.ProbeVolumePlugins()...) - allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) if utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) { allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...) diff --git a/cmd/kubelet/app/plugins.go b/cmd/kubelet/app/plugins.go index bbf2a133591..e05a21ef14d 100644 --- a/cmd/kubelet/app/plugins.go +++ b/cmd/kubelet/app/plugins.go @@ -38,7 +38,6 @@ import ( "k8s.io/kubernetes/pkg/volume/nfs" "k8s.io/kubernetes/pkg/volume/projected" "k8s.io/kubernetes/pkg/volume/secret" - "k8s.io/kubernetes/pkg/volume/storageos" // Cloud providers _ "k8s.io/kubernetes/pkg/cloudprovider/providers" @@ -72,7 +71,6 @@ func ProbeVolumePlugins(featureGate featuregate.FeatureGate) ([]volume.VolumePlu allPlugins = append(allPlugins, configmap.ProbeVolumePlugins()...) allPlugins = append(allPlugins, projected.ProbeVolumePlugins()...) allPlugins = append(allPlugins, local.ProbeVolumePlugins()...) - allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...) return allPlugins, nil } diff --git a/go.mod b/go.mod index 11b763fd34c..369574d4e6f 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,6 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/spf13/cobra v1.4.0 github.com/spf13/pflag v1.0.5 - github.com/storageos/go-api v2.2.0+incompatible github.com/stretchr/testify v1.7.0 github.com/vishvananda/netlink v1.1.0 github.com/vmware/govmomi v0.20.3 @@ -489,7 +488,6 @@ replace ( github.com/spf13/cobra => github.com/spf13/cobra v1.4.0 github.com/spf13/pflag => github.com/spf13/pflag v1.0.5 github.com/stoewer/go-strcase => github.com/stoewer/go-strcase v1.2.0 - github.com/storageos/go-api => github.com/storageos/go-api v2.2.0+incompatible github.com/stretchr/objx => github.com/stretchr/objx v0.2.0 github.com/stretchr/testify => github.com/stretchr/testify v1.7.0 github.com/syndtr/gocapability => github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 diff --git a/go.sum b/go.sum index 1f2623e756a..0654625f674 100644 --- a/go.sum +++ b/go.sum @@ -390,8 +390,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/storageos/go-api v2.2.0+incompatible h1:U0SablXoZIg06gvSlg8BCdzq1C/SkHVygOVX95Z2MU0= -github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= diff --git a/pkg/kubemark/hollow_kubelet.go b/pkg/kubemark/hollow_kubelet.go index dea85c04da9..ffc625b331e 100644 --- a/pkg/kubemark/hollow_kubelet.go +++ b/pkg/kubemark/hollow_kubelet.go @@ -54,7 +54,6 @@ import ( "k8s.io/kubernetes/pkg/volume/projected" "k8s.io/kubernetes/pkg/volume/rbd" "k8s.io/kubernetes/pkg/volume/secret" - "k8s.io/kubernetes/pkg/volume/storageos" "k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/test/utils" @@ -83,7 +82,6 @@ func volumePlugins() []volume.VolumePlugin { allPlugins = append(allPlugins, projected.ProbeVolumePlugins()...) allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...) allPlugins = append(allPlugins, local.ProbeVolumePlugins()...) - allPlugins = append(allPlugins, storageos.ProbeVolumePlugins()...) allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...) return allPlugins } diff --git a/pkg/volume/storageos/doc.go b/pkg/volume/storageos/doc.go deleted file mode 100644 index 764e8eeb463..00000000000 --- a/pkg/volume/storageos/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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 storageos contains the internal representation of StorageOS -// PersistentDisk volumes. -package storageos // import "k8s.io/kubernetes/pkg/volume/storageos" diff --git a/pkg/volume/storageos/storageos.go b/pkg/volume/storageos/storageos.go deleted file mode 100644 index d3d938d3b29..00000000000 --- a/pkg/volume/storageos/storageos.go +++ /dev/null @@ -1,762 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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 storageos - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - - "k8s.io/klog/v2" - "k8s.io/mount-utils" - utilexec "k8s.io/utils/exec" - utilstrings "k8s.io/utils/strings" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - clientset "k8s.io/client-go/kubernetes" - volumehelpers "k8s.io/cloud-provider/volume/helpers" - "k8s.io/kubernetes/pkg/volume" - "k8s.io/kubernetes/pkg/volume/util" -) - -// ProbeVolumePlugins is the primary entrypoint for volume plugins. -func ProbeVolumePlugins() []volume.VolumePlugin { - return []volume.VolumePlugin{&storageosPlugin{nil}} -} - -type storageosPlugin struct { - host volume.VolumeHost -} - -var _ volume.VolumePlugin = &storageosPlugin{} -var _ volume.PersistentVolumePlugin = &storageosPlugin{} -var _ volume.DeletableVolumePlugin = &storageosPlugin{} -var _ volume.ProvisionableVolumePlugin = &storageosPlugin{} - -const ( - storageosPluginName = "kubernetes.io/storageos" - defaultDeviceDir = "/var/lib/storageos/volumes" - defaultAPIAddress = "tcp://localhost:5705" - defaultAPIUser = "storageos" - defaultAPIPassword = "storageos" - defaultAPIVersion = "1" - defaultFSType = "ext4" - defaultNamespace = "default" -) - -func getPath(uid types.UID, volNamespace string, volName string, pvName string, host volume.VolumeHost) string { - if len(volNamespace) != 0 && len(volName) != 0 && strings.Count(volName, ".") == 0 { - return host.GetPodVolumeDir(uid, utilstrings.EscapeQualifiedName(storageosPluginName), pvName+"."+volNamespace+"."+volName) - } - return host.GetPodVolumeDir(uid, utilstrings.EscapeQualifiedName(storageosPluginName), pvName) -} - -func (plugin *storageosPlugin) Init(host volume.VolumeHost) error { - plugin.host = host - return nil -} - -func (plugin *storageosPlugin) GetPluginName() string { - return storageosPluginName -} - -func (plugin *storageosPlugin) GetVolumeName(spec *volume.Spec) (string, error) { - volumeSource, _, err := getVolumeSource(spec) - if err != nil { - return "", err - } - return fmt.Sprintf("%s/%s", volumeSource.VolumeNamespace, volumeSource.VolumeName), nil -} - -func (plugin *storageosPlugin) CanSupport(spec *volume.Spec) bool { - return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.StorageOS != nil) || - (spec.Volume != nil && spec.Volume.StorageOS != nil) -} - -func (plugin *storageosPlugin) RequiresRemount(spec *volume.Spec) bool { - return false -} - -func (plugin *storageosPlugin) GetAccessModes() []v1.PersistentVolumeAccessMode { - return []v1.PersistentVolumeAccessMode{ - v1.ReadWriteOnce, - v1.ReadOnlyMany, - } -} - -func (plugin *storageosPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.Mounter, error) { - - apiCfg, err := getAPICfg(spec, pod, plugin.host.GetKubeClient()) - if err != nil { - return nil, err - } - - return plugin.newMounterInternal(spec, pod, apiCfg, &storageosUtil{host: plugin.host}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName())) -} - -func (plugin *storageosPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, apiCfg *storageosAPIConfig, manager storageosManager, mounter mount.Interface, exec utilexec.Interface) (volume.Mounter, error) { - - volName, volNamespace, fsType, readOnly, err := getVolumeInfoFromSpec(spec) - if err != nil { - return nil, err - } - - return &storageosMounter{ - storageos: &storageos{ - podUID: pod.UID, - podNamespace: pod.GetNamespace(), - pvName: spec.Name(), - volName: volName, - volNamespace: volNamespace, - fsType: fsType, - readOnly: readOnly, - apiCfg: apiCfg, - manager: manager, - mounter: mounter, - exec: exec, - plugin: plugin, - MetricsProvider: volume.NewMetricsStatFS(getPath(pod.UID, volNamespace, volName, spec.Name(), plugin.host)), - }, - diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: exec}, - mountOptions: util.MountOptionFromSpec(spec), - }, nil -} - -func (plugin *storageosPlugin) NewUnmounter(pvName string, podUID types.UID) (volume.Unmounter, error) { - return plugin.newUnmounterInternal(pvName, podUID, &storageosUtil{host: plugin.host}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName())) -} - -func (plugin *storageosPlugin) newUnmounterInternal(pvName string, podUID types.UID, manager storageosManager, mounter mount.Interface, exec utilexec.Interface) (volume.Unmounter, error) { - - // Parse volume namespace & name from mountpoint if mounted - volNamespace, volName, err := getVolumeInfo(pvName, podUID, plugin.host) - if err != nil { - return nil, err - } - - return &storageosUnmounter{ - storageos: &storageos{ - podUID: podUID, - pvName: pvName, - volName: volName, - volNamespace: volNamespace, - manager: manager, - mounter: mounter, - exec: exec, - plugin: plugin, - MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, volNamespace, volName, pvName, plugin.host)), - }, - }, nil -} - -func (plugin *storageosPlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) { - if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.StorageOS == nil { - return nil, fmt.Errorf("spec.PersistentVolumeSource.StorageOS is nil") - } - - class, err := util.GetClassForVolume(plugin.host.GetKubeClient(), spec.PersistentVolume) - if err != nil { - return nil, err - } - - var adminSecretName, adminSecretNamespace string - - for k, v := range class.Parameters { - switch strings.ToLower(k) { - case "adminsecretname": - adminSecretName = v - case "adminsecretnamespace": - adminSecretNamespace = v - } - } - - apiCfg, err := parsePVSecret(adminSecretNamespace, adminSecretName, plugin.host.GetKubeClient()) - if err != nil { - return nil, fmt.Errorf("failed to get admin secret from [%q/%q]: %v", adminSecretNamespace, adminSecretName, err) - } - - return plugin.newDeleterInternal(spec, apiCfg, &storageosUtil{host: plugin.host}) -} - -func (plugin *storageosPlugin) newDeleterInternal(spec *volume.Spec, apiCfg *storageosAPIConfig, manager storageosManager) (volume.Deleter, error) { - - return &storageosDeleter{ - storageosMounter: &storageosMounter{ - storageos: &storageos{ - pvName: spec.Name(), - volName: spec.PersistentVolume.Spec.StorageOS.VolumeName, - volNamespace: spec.PersistentVolume.Spec.StorageOS.VolumeNamespace, - apiCfg: apiCfg, - manager: manager, - plugin: plugin, - }, - }, - pvUID: spec.PersistentVolume.UID, - }, nil -} - -func (plugin *storageosPlugin) NewProvisioner(options volume.VolumeOptions) (volume.Provisioner, error) { - return plugin.newProvisionerInternal(options, &storageosUtil{host: plugin.host}) -} - -func (plugin *storageosPlugin) newProvisionerInternal(options volume.VolumeOptions, manager storageosManager) (volume.Provisioner, error) { - return &storageosProvisioner{ - storageosMounter: &storageosMounter{ - storageos: &storageos{ - manager: manager, - plugin: plugin, - }, - }, - options: options, - }, nil -} - -func (plugin *storageosPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) { - volNamespace, volName, err := getVolumeFromRef(volumeName) - if err != nil { - volNamespace = defaultNamespace - volName = volumeName - } - storageosVolume := &v1.Volume{ - Name: volumeName, - VolumeSource: v1.VolumeSource{ - StorageOS: &v1.StorageOSVolumeSource{ - VolumeName: volName, - VolumeNamespace: volNamespace, - }, - }, - } - return volume.NewSpecFromVolume(storageosVolume), nil -} - -func (plugin *storageosPlugin) SupportsMountOption() bool { - return true -} - -func (plugin *storageosPlugin) SupportsBulkVolumeVerification() bool { - return false -} - -func getVolumeSource(spec *volume.Spec) (*v1.StorageOSVolumeSource, bool, error) { - if spec.Volume != nil && spec.Volume.StorageOS != nil { - return spec.Volume.StorageOS, spec.Volume.StorageOS.ReadOnly, nil - } - return nil, false, fmt.Errorf("Spec does not reference a StorageOS volume type") -} - -func getPersistentVolumeSource(spec *volume.Spec) (*v1.StorageOSPersistentVolumeSource, bool, error) { - if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.StorageOS != nil { - return spec.PersistentVolume.Spec.StorageOS, spec.ReadOnly, nil - } - return nil, false, fmt.Errorf("Spec does not reference a StorageOS persistent volume type") -} - -// storageosManager is the abstract interface to StorageOS volume ops. -type storageosManager interface { - // Connects to the StorageOS API using the supplied configuration. - NewAPI(apiCfg *storageosAPIConfig) error - // Creates a StorageOS volume. - CreateVolume(provisioner *storageosProvisioner) (*storageosVolume, error) - // Attaches the disk to the kubelet's host machine. - AttachVolume(mounter *storageosMounter) (string, error) - // Attaches the device to the host at a mount path. - AttachDevice(mounter *storageosMounter, deviceMountPath string) error - // Detaches the disk from the kubelet's host machine. - DetachVolume(unmounter *storageosUnmounter, dir string) error - // Mounts the disk on the Kubelet's host machine. - MountVolume(mounter *storageosMounter, mnt, dir string) error - // Unmounts the disk from the Kubelet's host machine. - UnmountVolume(unounter *storageosUnmounter) error - // Deletes the storageos volume. All data will be lost. - DeleteVolume(deleter *storageosDeleter) error - // Gets the node's device path. - DeviceDir(mounter *storageosMounter) string -} - -// storageos volumes represent a bare host directory mount of an StorageOS export. -type storageos struct { - podUID types.UID - podNamespace string - pvName string - volName string - volNamespace string - readOnly bool - description string - pool string - fsType string - sizeGB int - labels map[string]string - apiCfg *storageosAPIConfig - manager storageosManager - mounter mount.Interface - exec utilexec.Interface - plugin *storageosPlugin - volume.MetricsProvider -} - -type storageosMounter struct { - *storageos - - // The directory containing the StorageOS devices - deviceDir string - - // Interface used to mount the file or block device - diskMounter *mount.SafeFormatAndMount - mountOptions []string -} - -var _ volume.Mounter = &storageosMounter{} - -func (b *storageosMounter) GetAttributes() volume.Attributes { - return volume.Attributes{ - ReadOnly: b.readOnly, - Managed: !b.readOnly, - SELinuxRelabel: true, - } -} - -// SetUp attaches the disk and bind mounts to the volume path. -func (b *storageosMounter) SetUp(mounterArgs volume.MounterArgs) error { - // Need a namespace to find the volume, try pod's namespace if not set. - if b.volNamespace == "" { - klog.V(2).Infof("Setting StorageOS volume namespace to pod namespace: %s", b.podNamespace) - b.volNamespace = b.podNamespace - } - - targetPath := makeGlobalPDName(b.plugin.host, b.pvName, b.volNamespace, b.volName) - - // Attach the device to the host. - if err := b.manager.AttachDevice(b, targetPath); err != nil { - klog.Errorf("Failed to attach device at %s: %s", targetPath, err.Error()) - return err - } - - // Attach the StorageOS volume as a block device - devicePath, err := b.manager.AttachVolume(b) - if err != nil { - klog.Errorf("Failed to attach StorageOS volume %s: %s", b.volName, err.Error()) - return err - } - - // Mount the loop device into the plugin's disk global mount dir. - err = b.manager.MountVolume(b, devicePath, targetPath) - if err != nil { - return err - } - klog.V(4).Infof("Successfully mounted StorageOS volume %s into global mount directory", b.volName) - - // Bind mount the volume into the pod - return b.SetUpAt(b.GetPath(), mounterArgs) -} - -// SetUp bind mounts the disk global mount to the give volume path. -func (b *storageosMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { - notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) - klog.V(4).Infof("StorageOS volume set up: %s %v %v", dir, !notMnt, err) - if err != nil && !os.IsNotExist(err) { - klog.Errorf("Cannot validate mount point: %s %v", dir, err) - return err - } - if !notMnt { - return nil - } - - if err = os.MkdirAll(dir, 0750); err != nil { - klog.Errorf("mkdir failed on disk %s (%v)", dir, err) - return err - } - - // Perform a bind mount to the full path to allow duplicate mounts of the same PD. - options := []string{"bind"} - if b.readOnly { - options = append(options, "ro") - } - mountOptions := util.JoinMountOptions(b.mountOptions, options) - - globalPDPath := makeGlobalPDName(b.plugin.host, b.pvName, b.volNamespace, b.volName) - klog.V(4).Infof("Attempting to bind mount to pod volume at %s", dir) - - err = b.mounter.MountSensitiveWithoutSystemd(globalPDPath, dir, "", mountOptions, nil) - if err != nil { - notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) - if mntErr != nil { - klog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) - return err - } - if !notMnt { - if mntErr = b.mounter.Unmount(dir); mntErr != nil { - klog.Errorf("Failed to unmount: %v", mntErr) - return err - } - notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) - if mntErr != nil { - klog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) - return err - } - if !notMnt { - klog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", dir) - return err - } - } - os.Remove(dir) - klog.Errorf("Mount of disk %s failed: %v", dir, err) - return err - } - - if !b.readOnly { - volume.SetVolumeOwnership(b, mounterArgs.FsGroup, mounterArgs.FSGroupChangePolicy, util.FSGroupCompleteHook(b.plugin, nil)) - } - klog.V(4).Infof("StorageOS volume setup complete on %s", dir) - return nil -} - -func makeGlobalPDName(host volume.VolumeHost, pvName, volNamespace, volName string) string { - return filepath.Join(host.GetPluginDir(utilstrings.EscapeQualifiedName(storageosPluginName)), util.MountsInGlobalPDPath, pvName+"."+volNamespace+"."+volName) -} - -// Given the pod id and PV name, finds the volume's namespace and name from the -// name or volume mount. We mount as volNamespace.pvName, but k8s will specify -// only the pvName to unmount. -// Will return empty volNamespace/pvName if the volume is not mounted. -func getVolumeInfo(pvName string, podUID types.UID, host volume.VolumeHost) (string, string, error) { - if volNamespace, volName, err := getVolumeFromRef(pvName); err == nil { - return volNamespace, volName, nil - } - - volumeDir := filepath.Dir(host.GetPodVolumeDir(podUID, utilstrings.EscapeQualifiedName(storageosPluginName), pvName)) - files, err := ioutil.ReadDir(volumeDir) - if err != nil { - return "", "", fmt.Errorf("could not read mounts from pod volume dir: %s", err) - } - for _, f := range files { - if f.Mode().IsDir() && strings.HasPrefix(f.Name(), pvName+".") { - if volNamespace, volName, err := getVolumeFromRef(f.Name()); err == nil { - return volNamespace, volName, nil - } - } - } - return "", "", fmt.Errorf("could not get info from unmounted pv %q at %q", pvName, volumeDir) -} - -// Splits the volume ref on "." to return the volNamespace and pvName. Neither -// namespaces nor service names allow "." in their names. -func getVolumeFromRef(ref string) (volNamespace string, volName string, err error) { - refParts := strings.Split(ref, ".") - switch len(refParts) { - case 2: - return refParts[0], refParts[1], nil - case 3: - return refParts[1], refParts[2], nil - } - return "", "", fmt.Errorf("ref not in format volNamespace.volName or pvName.volNamespace.volName") -} - -// GetPath returns the path to the user specific mount of a StorageOS volume -func (storageosVolume *storageos) GetPath() string { - return getPath(storageosVolume.podUID, storageosVolume.volNamespace, storageosVolume.volName, storageosVolume.pvName, storageosVolume.plugin.host) -} - -type storageosUnmounter struct { - *storageos -} - -var _ volume.Unmounter = &storageosUnmounter{} - -func (b *storageosUnmounter) GetPath() string { - return getPath(b.podUID, b.volNamespace, b.volName, b.pvName, b.plugin.host) -} - -// Unmounts the bind mount, and detaches the disk only if the PD -// resource was the last reference to that disk on the kubelet. -func (b *storageosUnmounter) TearDown() error { - if len(b.volNamespace) == 0 || len(b.volName) == 0 { - klog.Warningf("volNamespace: %q, volName: %q not set, skipping TearDown", b.volNamespace, b.volName) - return fmt.Errorf("pvName not specified for TearDown, waiting for next sync loop") - } - // Unmount from pod - mountPath := b.GetPath() - - err := b.TearDownAt(mountPath) - if err != nil { - klog.Errorf("Unmount from pod failed: %v", err) - return err - } - - // Find device name from global mount - globalPDPath := makeGlobalPDName(b.plugin.host, b.pvName, b.volNamespace, b.volName) - devicePath, _, err := mount.GetDeviceNameFromMount(b.mounter, globalPDPath) - if err != nil { - klog.Errorf("Detach failed when getting device from global mount: %v", err) - return err - } - - // Unmount from plugin's disk global mount dir. - err = b.TearDownAt(globalPDPath) - if err != nil { - klog.Errorf("Detach failed during unmount: %v", err) - return err - } - - // Detach loop device - err = b.manager.DetachVolume(b, devicePath) - if err != nil { - klog.Errorf("Detach device %s failed for volume %s: %v", devicePath, b.pvName, err) - return err - } - - klog.V(4).Infof("Successfully unmounted StorageOS volume %s and detached devices", b.pvName) - - return nil -} - -// Unmounts the bind mount, and detaches the disk only if the PD -// resource was the last reference to that disk on the kubelet. -func (b *storageosUnmounter) TearDownAt(dir string) error { - if err := mount.CleanupMountPoint(dir, b.mounter, false); err != nil { - klog.V(4).Infof("Unmounted StorageOS volume %s failed with: %v", b.pvName, err) - } - if err := b.manager.UnmountVolume(b); err != nil { - klog.V(4).Infof("Mount reference for volume %s could not be removed from StorageOS: %v", b.pvName, err) - } - return nil -} - -type storageosDeleter struct { - *storageosMounter - pvUID types.UID -} - -var _ volume.Deleter = &storageosDeleter{} - -func (d *storageosDeleter) GetPath() string { - return getPath(d.podUID, d.volNamespace, d.volName, d.pvName, d.plugin.host) -} - -func (d *storageosDeleter) Delete() error { - return d.manager.DeleteVolume(d) -} - -type storageosProvisioner struct { - *storageosMounter - options volume.VolumeOptions -} - -var _ volume.Provisioner = &storageosProvisioner{} - -func (c *storageosProvisioner) Provision(selectedNode *v1.Node, allowedTopologies []v1.TopologySelectorTerm) (*v1.PersistentVolume, error) { - if !util.ContainsAllAccessModes(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) { - return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes()) - } - if util.CheckPersistentVolumeClaimModeBlock(c.options.PVC) { - return nil, fmt.Errorf("%s does not support block volume provisioning", c.plugin.GetPluginName()) - } - - var adminSecretName, adminSecretNamespace string - - // Apply ProvisionerParameters (case-insensitive). We leave validation of - // the values to the cloud provider. - for k, v := range c.options.Parameters { - switch strings.ToLower(k) { - case "adminsecretname": - adminSecretName = v - case "adminsecretnamespace": - adminSecretNamespace = v - case "volumenamespace": - c.volNamespace = v - case "description": - c.description = v - case "pool": - c.pool = v - case "fstype": - c.fsType = v - default: - return nil, fmt.Errorf("invalid option %q for volume plugin %s", k, c.plugin.GetPluginName()) - } - } - - // Set from PVC - c.podNamespace = c.options.PVC.Namespace - c.volName = c.options.PVName - if c.volNamespace == "" { - c.volNamespace = c.options.PVC.Namespace - } - c.labels = make(map[string]string) - for k, v := range c.options.PVC.Labels { - c.labels[k] = v - } - capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] - var err error - c.sizeGB, err = volumehelpers.RoundUpToGiBInt(capacity) - if err != nil { - return nil, err - } - - apiCfg, err := parsePVSecret(adminSecretNamespace, adminSecretName, c.plugin.host.GetKubeClient()) - if err != nil { - return nil, err - } - c.apiCfg = apiCfg - - vol, err := c.manager.CreateVolume(c) - if err != nil { - klog.Errorf("failed to create volume: %v", err) - return nil, err - } - if vol.FSType == "" { - vol.FSType = defaultFSType - } - - pv := &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: vol.Name, - Labels: map[string]string{}, - Annotations: map[string]string{ - util.VolumeDynamicallyCreatedByKey: "storageos-dynamic-provisioner", - }, - }, - Spec: v1.PersistentVolumeSpec{ - PersistentVolumeReclaimPolicy: c.options.PersistentVolumeReclaimPolicy, - AccessModes: c.options.PVC.Spec.AccessModes, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", vol.SizeGB)), - }, - PersistentVolumeSource: v1.PersistentVolumeSource{ - StorageOS: &v1.StorageOSPersistentVolumeSource{ - VolumeName: vol.Name, - VolumeNamespace: vol.Namespace, - FSType: vol.FSType, - ReadOnly: false, - SecretRef: &v1.ObjectReference{ - Name: adminSecretName, - Namespace: adminSecretNamespace, - }, - }, - }, - MountOptions: c.options.MountOptions, - }, - } - if len(c.options.PVC.Spec.AccessModes) == 0 { - pv.Spec.AccessModes = c.plugin.GetAccessModes() - } - if len(vol.Labels) != 0 { - if pv.Labels == nil { - pv.Labels = make(map[string]string) - } - for k, v := range vol.Labels { - pv.Labels[k] = v - } - } - return pv, nil -} - -// Returns StorageOS volume name, namespace, fstype and readonly from spec -func getVolumeInfoFromSpec(spec *volume.Spec) (string, string, string, bool, error) { - if spec.PersistentVolume != nil { - source, readOnly, err := getPersistentVolumeSource(spec) - if err != nil { - return "", "", "", false, err - } - return source.VolumeName, source.VolumeNamespace, source.FSType, readOnly, nil - } - - if spec.Volume != nil { - source, readOnly, err := getVolumeSource(spec) - if err != nil { - return "", "", "", false, err - } - return source.VolumeName, source.VolumeNamespace, source.FSType, readOnly, nil - } - return "", "", "", false, fmt.Errorf("spec not Volume or PersistentVolume") -} - -// Returns API config if secret set, otherwise empty struct so defaults can be -// attempted. -func getAPICfg(spec *volume.Spec, pod *v1.Pod, kubeClient clientset.Interface) (*storageosAPIConfig, error) { - if spec.PersistentVolume != nil { - source, _, err := getPersistentVolumeSource(spec) - if err != nil { - return nil, err - } - if source.SecretRef == nil { - return nil, nil - } - return parsePVSecret(source.SecretRef.Namespace, source.SecretRef.Name, kubeClient) - } - - if spec.Volume != nil { - source, _, err := getVolumeSource(spec) - if err != nil { - return nil, err - } - if source.SecretRef == nil { - return nil, nil - } - return parsePodSecret(pod, source.SecretRef.Name, kubeClient) - } - - return nil, fmt.Errorf("spec not Volume or PersistentVolume") -} - -func parsePodSecret(pod *v1.Pod, secretName string, kubeClient clientset.Interface) (*storageosAPIConfig, error) { - secret, err := util.GetSecretForPod(pod, secretName, kubeClient) - if err != nil { - klog.Errorf("failed to get secret from [%q/%q]", pod.Namespace, secretName) - return nil, fmt.Errorf("failed to get secret from [%q/%q]", pod.Namespace, secretName) - } - return parseAPIConfig(secret) -} - -// Important: Only to be called with data from a PV to avoid secrets being -// loaded from a user-suppler namespace. -func parsePVSecret(namespace, secretName string, kubeClient clientset.Interface) (*storageosAPIConfig, error) { - secret, err := util.GetSecretForPV(namespace, secretName, storageosPluginName, kubeClient) - if err != nil { - klog.Errorf("failed to get secret from [%q/%q]", namespace, secretName) - return nil, fmt.Errorf("failed to get secret from [%q/%q]", namespace, secretName) - } - return parseAPIConfig(secret) -} - -// Parse API configuration from parameters or secret -func parseAPIConfig(params map[string]string) (*storageosAPIConfig, error) { - - if len(params) == 0 { - return nil, fmt.Errorf("empty API config") - } - - c := &storageosAPIConfig{} - - for name, data := range params { - switch strings.ToLower(name) { - case "apiaddress": - c.apiAddr = string(data) - case "apiusername": - c.apiUser = string(data) - case "apipassword": - c.apiPass = string(data) - case "apiversion": - c.apiVersion = string(data) - } - } - - return c, nil -} diff --git a/pkg/volume/storageos/storageos_test.go b/pkg/volume/storageos/storageos_test.go deleted file mode 100644 index 5efb509b519..00000000000 --- a/pkg/volume/storageos/storageos_test.go +++ /dev/null @@ -1,384 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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 storageos - -import ( - "context" - "fmt" - "os" - "path/filepath" - "testing" - - "k8s.io/mount-utils" - "k8s.io/utils/exec/testing" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/fake" - utiltesting "k8s.io/client-go/util/testing" - "k8s.io/kubernetes/pkg/volume" - volumetest "k8s.io/kubernetes/pkg/volume/testing" -) - -func TestCanSupport(t *testing.T) { - tmpDir, err := utiltesting.MkTmpdir("storageos_test") - if err != nil { - t.Fatalf("error creating temp dir: %v", err) - } - defer os.RemoveAll(tmpDir) - plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)) - - plug, err := plugMgr.FindPluginByName("kubernetes.io/storageos") - if err != nil { - t.Fatal("Can't find the plugin by name") - } - if plug.GetPluginName() != "kubernetes.io/storageos" { - t.Errorf("Wrong name: %s", plug.GetPluginName()) - } - if !plug.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{StorageOS: &v1.StorageOSVolumeSource{}}}}) { - t.Errorf("Expected true") - } - if !plug.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{StorageOS: &v1.StorageOSPersistentVolumeSource{}}}}}) { - t.Errorf("Expected true") - } -} - -func TestGetAccessModes(t *testing.T) { - tmpDir, err := utiltesting.MkTmpdir("storageos_test") - if err != nil { - t.Fatalf("error creating temp dir: %v", err) - } - defer os.RemoveAll(tmpDir) - plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)) - - plug, err := plugMgr.FindPersistentPluginByName("kubernetes.io/storageos") - if err != nil { - t.Errorf("Can't find the plugin by name") - } - if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) { - t.Errorf("Expected two AccessModeTypes: %s and %s", v1.ReadWriteOnce, v1.ReadOnlyMany) - } -} - -type fakePDManager struct { - api apiImplementer - attachCalled bool - attachDeviceCalled bool - detachCalled bool - mountCalled bool - unmountCalled bool - createCalled bool - deleteCalled bool -} - -func (fake *fakePDManager) NewAPI(apiCfg *storageosAPIConfig) error { - fake.api = fakeAPI{} - return nil -} - -func (fake *fakePDManager) CreateVolume(p *storageosProvisioner) (*storageosVolume, error) { - fake.createCalled = true - labels := make(map[string]string) - labels["fakepdmanager"] = "yes" - return &storageosVolume{ - Name: "test-storageos-name", - Namespace: "test-storageos-namespace", - Pool: "test-storageos-pool", - SizeGB: 100, - Labels: labels, - FSType: "ext2", - }, nil -} - -func (fake *fakePDManager) AttachVolume(b *storageosMounter) (string, error) { - fake.attachCalled = true - return "", nil -} - -func (fake *fakePDManager) AttachDevice(b *storageosMounter, dir string) error { - fake.attachDeviceCalled = true - return nil -} - -func (fake *fakePDManager) DetachVolume(b *storageosUnmounter, loopDevice string) error { - fake.detachCalled = true - return nil -} - -func (fake *fakePDManager) MountVolume(b *storageosMounter, mntDevice, deviceMountPath string) error { - fake.mountCalled = true - return nil -} - -func (fake *fakePDManager) UnmountVolume(b *storageosUnmounter) error { - fake.unmountCalled = true - return nil -} - -func (fake *fakePDManager) DeleteVolume(d *storageosDeleter) error { - fake.deleteCalled = true - if d.volName != "test-storageos-name" { - return fmt.Errorf("Deleter got unexpected volume name: %s", d.volName) - } - return nil -} - -func (fake *fakePDManager) DeviceDir(mounter *storageosMounter) string { - return defaultDeviceDir -} - -func TestPlugin(t *testing.T) { - tmpDir, err := utiltesting.MkTmpdir("storageos_test") - if err != nil { - t.Fatalf("can't make a temp dir: %v", err) - } - defer os.RemoveAll(tmpDir) - plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)) - - plug, err := plugMgr.FindPluginByName("kubernetes.io/storageos") - if err != nil { - t.Errorf("Can't find the plugin by name") - } - secretName := "very-secret" - spec := &v1.Volume{ - Name: "vol1-pvname", - VolumeSource: v1.VolumeSource{ - StorageOS: &v1.StorageOSVolumeSource{ - VolumeName: "vol1", - VolumeNamespace: "ns1", - FSType: "ext3", - SecretRef: &v1.LocalObjectReference{ - Name: secretName, - }, - }, - }, - } - - client := fake.NewSimpleClientset() - - client.CoreV1().Secrets("default").Create(context.TODO(), &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: secretName, - Namespace: "default", - }, - Type: "kubernetes.io/storageos", - Data: map[string][]byte{ - "apiUsername": []byte("storageos"), - "apiPassword": []byte("storageos"), - "apiAddr": []byte("tcp://localhost:5705"), - }}, metav1.CreateOptions{}) - - plug.(*storageosPlugin).host = volumetest.NewFakeVolumeHost(t, tmpDir, client, nil) - - // Test Mounter - pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid"), Namespace: "default"}} - fakeManager := &fakePDManager{} - - apiCfg, err := parsePodSecret(pod, secretName, plug.(*storageosPlugin).host.GetKubeClient()) - if err != nil { - t.Errorf("Couldn't get secret from %v/%v", pod.Namespace, secretName) - } - - mounter, err := plug.(*storageosPlugin).newMounterInternal(volume.NewSpecFromVolume(spec), pod, apiCfg, fakeManager, mount.NewFakeMounter(nil), &testingexec.FakeExec{}) - if err != nil { - t.Fatalf("Failed to make a new Mounter: %v", err) - } - if mounter == nil { - t.Fatalf("Got a nil Mounter") - } - - expectedPath := filepath.Join(tmpDir, "pods/poduid/volumes/kubernetes.io~storageos/vol1-pvname.ns1.vol1") - volPath := mounter.GetPath() - if volPath != expectedPath { - t.Errorf("Expected path: '%s' got: '%s'", expectedPath, volPath) - } - - if err := mounter.SetUp(volume.MounterArgs{}); err != nil { - t.Errorf("Expected success, got: %v", err) - } - if _, err := os.Stat(volPath); err != nil { - if os.IsNotExist(err) { - t.Errorf("SetUp() failed, volume path not created: %s", volPath) - } else { - t.Errorf("SetUp() failed: %v", err) - } - } - - if !fakeManager.attachDeviceCalled { - t.Errorf("AttachDevice not called") - } - if !fakeManager.attachCalled { - t.Errorf("Attach not called") - } - if !fakeManager.mountCalled { - t.Errorf("Mount not called") - } - - // Test Unmounter - fakeManager = &fakePDManager{} - unmounter, err := plug.(*storageosPlugin).newUnmounterInternal("vol1-pvname", types.UID("poduid"), fakeManager, mount.NewFakeMounter(nil), &testingexec.FakeExec{}) - if err != nil { - t.Errorf("Failed to make a new Unmounter: %v", err) - } - if unmounter == nil { - t.Errorf("Got a nil Unmounter") - } - - volPath = unmounter.GetPath() - if volPath != expectedPath { - t.Errorf("Expected path: '%s' got: '%s'", expectedPath, volPath) - } - - if err := unmounter.TearDown(); err != nil { - t.Errorf("Expected success, got: %v", err) - } - if _, err := os.Stat(volPath); err == nil { - t.Errorf("TearDown() failed, volume path still exists: %s", volPath) - } else if !os.IsNotExist(err) { - t.Errorf("TearDown() failed: %v", err) - } - - if !fakeManager.unmountCalled { - t.Errorf("Unmount not called") - } - if !fakeManager.detachCalled { - t.Errorf("Detach not called") - } - - // Test Provisioner - fakeManager = &fakePDManager{} - mountOptions := []string{"sync", "noatime"} - options := volume.VolumeOptions{ - PVC: volumetest.CreateTestPVC("100Mi", []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}), - // PVName: "test-volume-name", - PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete, - Parameters: map[string]string{ - "VolumeNamespace": "test-volume-namespace", - "adminSecretName": secretName, - "adminsecretnamespace": "default", - }, - MountOptions: mountOptions, - } - provisioner, err := plug.(*storageosPlugin).newProvisionerInternal(options, fakeManager) - if err != nil { - t.Errorf("newProvisionerInternal() failed: %v", err) - } - - persistentSpec, err := provisioner.Provision(nil, nil) - if err != nil { - t.Fatalf("Provision() failed: %v", err) - } - - if persistentSpec.Spec.PersistentVolumeSource.StorageOS.VolumeName != "test-storageos-name" { - t.Errorf("Provision() returned unexpected volume Name: %s, expected test-storageos-name", persistentSpec.Spec.PersistentVolumeSource.StorageOS.VolumeName) - } - if persistentSpec.Spec.PersistentVolumeSource.StorageOS.VolumeNamespace != "test-storageos-namespace" { - t.Errorf("Provision() returned unexpected volume Namespace: %s", persistentSpec.Spec.PersistentVolumeSource.StorageOS.VolumeNamespace) - } - cap := persistentSpec.Spec.Capacity[v1.ResourceStorage] - size := cap.Value() - if size != 100*1024*1024*1024 { - t.Errorf("Provision() returned unexpected volume size: %v", size) - } - if persistentSpec.Spec.PersistentVolumeSource.StorageOS.FSType != "ext2" { - t.Errorf("Provision() returned unexpected volume FSType: %s", persistentSpec.Spec.PersistentVolumeSource.StorageOS.FSType) - } - if len(persistentSpec.Spec.MountOptions) != 2 { - t.Errorf("Provision() returned unexpected volume mount options: %v", persistentSpec.Spec.MountOptions) - } - if persistentSpec.Labels["fakepdmanager"] != "yes" { - t.Errorf("Provision() returned unexpected labels: %v", persistentSpec.Labels) - } - if !fakeManager.createCalled { - t.Errorf("Create not called") - } - - // Test Deleter - fakeManager = &fakePDManager{} - volSpec := &volume.Spec{ - PersistentVolume: persistentSpec, - } - deleter, err := plug.(*storageosPlugin).newDeleterInternal(volSpec, apiCfg, fakeManager) - if err != nil { - t.Errorf("newDeleterInternal() failed: %v", err) - } - - err = deleter.Delete() - if err != nil { - t.Errorf("Deleter() failed: %v", err) - } - if !fakeManager.deleteCalled { - t.Errorf("Delete not called") - } -} - -func TestPersistentClaimReadOnlyFlag(t *testing.T) { - tmpDir, err := utiltesting.MkTmpdir("storageos_test") - if err != nil { - t.Fatalf("error creating temp dir: %v", err) - } - defer os.RemoveAll(tmpDir) - - pv := &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pvA", - }, - Spec: v1.PersistentVolumeSpec{ - PersistentVolumeSource: v1.PersistentVolumeSource{ - StorageOS: &v1.StorageOSPersistentVolumeSource{VolumeName: "pvA", VolumeNamespace: "vnsA", ReadOnly: false}, - }, - ClaimRef: &v1.ObjectReference{ - Name: "claimA", - }, - }, - } - - claim := &v1.PersistentVolumeClaim{ - ObjectMeta: metav1.ObjectMeta{ - Name: "claimA", - Namespace: "nsA", - }, - Spec: v1.PersistentVolumeClaimSpec{ - VolumeName: "pvA", - }, - Status: v1.PersistentVolumeClaimStatus{ - Phase: v1.ClaimBound, - }, - } - - client := fake.NewSimpleClientset(pv, claim) - plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, client, nil)) - plug, _ := plugMgr.FindPluginByName(storageosPluginName) - - // readOnly bool is supplied by persistent-claim volume source when its mounter creates other volumes - spec := volume.NewSpecFromPersistentVolume(pv, true) - pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "nsA", UID: types.UID("poduid")}} - fakeManager := &fakePDManager{} - apiCfg := GetAPIConfig() - mounter, err := plug.(*storageosPlugin).newMounterInternal(spec, pod, apiCfg, fakeManager, mount.NewFakeMounter(nil), &testingexec.FakeExec{}) - if err != nil { - t.Fatalf("error creating a new internal mounter:%v", err) - } - if !mounter.GetAttributes().ReadOnly { - t.Errorf("Expected true for mounter.IsReadOnly") - } -} diff --git a/pkg/volume/storageos/storageos_util.go b/pkg/volume/storageos/storageos_util.go deleted file mode 100644 index 3199c915709..00000000000 --- a/pkg/volume/storageos/storageos_util.go +++ /dev/null @@ -1,436 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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 storageos - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - - storageosapi "github.com/storageos/go-api" - storageostypes "github.com/storageos/go-api/types" - "k8s.io/klog/v2" - proxyutil "k8s.io/kubernetes/pkg/proxy/util" - "k8s.io/kubernetes/pkg/volume" - utilexec "k8s.io/utils/exec" -) - -const ( - losetupPath = "losetup" - - modeBlock deviceType = iota - modeFile - modeUnsupported - - //ErrDeviceNotFound defines "device not found" - ErrDeviceNotFound = "device not found" - //ErrDeviceNotSupported defines "device not supported" - ErrDeviceNotSupported = "device not supported" - //ErrNotAvailable defines "not available" - ErrNotAvailable = "not available" -) - -type deviceType int - -// storageosVolume describes a provisioned volume -type storageosVolume struct { - ID string - Name string - Namespace string - Description string - Pool string - SizeGB int - Labels map[string]string - FSType string -} - -type storageosAPIConfig struct { - apiAddr string - apiUser string - apiPass string - apiVersion string -} - -type apiImplementer interface { - Volume(namespace string, ref string) (*storageostypes.Volume, error) - VolumeCreate(opts storageostypes.VolumeCreateOptions) (*storageostypes.Volume, error) - VolumeMount(opts storageostypes.VolumeMountOptions) error - VolumeUnmount(opts storageostypes.VolumeUnmountOptions) error - VolumeDelete(opt storageostypes.DeleteOptions) error - Node(ref string) (*storageostypes.Node, error) -} - -// storageosUtil is the utility structure to interact with the StorageOS API. -type storageosUtil struct { - api apiImplementer - host volume.VolumeHost -} - -func (u *storageosUtil) NewAPI(apiCfg *storageosAPIConfig) error { - if u.api != nil { - return nil - } - if u.host == nil { - return errors.New("host must not be nil") - } - if apiCfg == nil { - apiCfg = &storageosAPIConfig{ - apiAddr: defaultAPIAddress, - apiUser: defaultAPIUser, - apiPass: defaultAPIPassword, - apiVersion: defaultAPIVersion, - } - klog.V(4).Infof("using default StorageOS API settings: addr %s, version: %s", apiCfg.apiAddr, defaultAPIVersion) - } - - api, err := storageosapi.NewVersionedClient(apiCfg.apiAddr, defaultAPIVersion) - if err != nil { - return err - } - api.SetAuth(apiCfg.apiUser, apiCfg.apiPass) - if err := api.SetDialContext(proxyutil.NewFilteredDialContext(api.GetDialContext(), nil, u.host.GetFilteredDialOptions())); err != nil { - return fmt.Errorf("failed to set DialContext in storageos client: %v", err) - } - u.api = api - return nil -} - -// Creates a new StorageOS volume and makes it available as a device within -// /var/lib/storageos/volumes. -func (u *storageosUtil) CreateVolume(p *storageosProvisioner) (*storageosVolume, error) { - - klog.V(4).Infof("creating StorageOS volume %q with namespace %q", p.volName, p.volNamespace) - - if err := u.NewAPI(p.apiCfg); err != nil { - return nil, err - } - - if p.labels == nil { - p.labels = make(map[string]string) - } - opts := storageostypes.VolumeCreateOptions{ - Name: p.volName, - Size: p.sizeGB, - Description: p.description, - Pool: p.pool, - FSType: p.fsType, - Namespace: p.volNamespace, - Labels: p.labels, - } - - vol, err := u.api.VolumeCreate(opts) - if err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("volume create failed for volume %q (%v)", opts.Name, err) - return nil, errors.New("volume create failed: see kube-controller-manager.log for details") - } - return &storageosVolume{ - ID: vol.ID, - Name: vol.Name, - Namespace: vol.Namespace, - Description: vol.Description, - Pool: vol.Pool, - FSType: vol.FSType, - SizeGB: int(vol.Size), - Labels: vol.Labels, - }, nil -} - -// Attach exposes a volume on the host as a block device. StorageOS uses a -// global namespace, so if the volume exists, it should already be available as -// a device within `/var/lib/storageos/volumes/`. -// -// Depending on the host capabilities, the device may be either a block device -// or a file device. Block devices can be used directly, but file devices must -// be made accessible as a block device before using. -func (u *storageosUtil) AttachVolume(b *storageosMounter) (string, error) { - - klog.V(4).Infof("attaching StorageOS volume %q with namespace %q", b.volName, b.volNamespace) - - if err := u.NewAPI(b.apiCfg); err != nil { - return "", err - } - - // Get the node's device path from the API, falling back to the default if - // not set on the node. - if b.deviceDir == "" { - b.deviceDir = u.DeviceDir(b) - } - - vol, err := u.api.Volume(b.volNamespace, b.volName) - if err != nil { - klog.Warningf("volume retrieve failed for volume %q with namespace %q (%v)", b.volName, b.volNamespace, err) - return "", err - } - - srcPath := filepath.Join(b.deviceDir, vol.ID) - dt, err := pathDeviceType(srcPath) - if err != nil { - klog.Warningf("volume source path %q for volume %q not ready (%v)", srcPath, b.volName, err) - return "", err - } - - switch dt { - case modeBlock: - return srcPath, nil - case modeFile: - return attachFileDevice(srcPath, b.exec) - default: - return "", fmt.Errorf(ErrDeviceNotSupported) - } -} - -// Detach detaches a volume from the host. This is only needed when NBD is not -// enabled and loop devices are used to simulate a block device. -func (u *storageosUtil) DetachVolume(b *storageosUnmounter, devicePath string) error { - - klog.V(4).Infof("detaching StorageOS volume %q with namespace %q", b.volName, b.volNamespace) - - if !isLoopDevice(devicePath) { - return nil - } - if _, err := os.Stat(devicePath); os.IsNotExist(err) { - return nil - } - return removeLoopDevice(devicePath, b.exec) -} - -// AttachDevice attaches the volume device to the host at a given mount path. -func (u *storageosUtil) AttachDevice(b *storageosMounter, deviceMountPath string) error { - - klog.V(4).Infof("attaching StorageOS device for volume %q with namespace %q", b.volName, b.volNamespace) - - if err := u.NewAPI(b.apiCfg); err != nil { - return err - } - - opts := storageostypes.VolumeMountOptions{ - Name: b.volName, - Namespace: b.volNamespace, - FsType: b.fsType, - Mountpoint: deviceMountPath, - Client: b.plugin.host.GetHostName(), - } - if err := u.api.VolumeMount(opts); err != nil { - return err - } - return nil -} - -// Mount mounts the volume on the host. -func (u *storageosUtil) MountVolume(b *storageosMounter, mntDevice, deviceMountPath string) error { - - klog.V(4).Infof("mounting StorageOS volume %q with namespace %q", b.volName, b.volNamespace) - - notMnt, err := b.mounter.IsLikelyNotMountPoint(deviceMountPath) - if err != nil { - if os.IsNotExist(err) { - if err = os.MkdirAll(deviceMountPath, 0750); err != nil { - return err - } - notMnt = true - } else { - return err - } - } - if err = os.MkdirAll(deviceMountPath, 0750); err != nil { - klog.Errorf("mkdir failed on disk %s (%v)", deviceMountPath, err) - return err - } - options := []string{} - if b.readOnly { - options = append(options, "ro") - } - if notMnt { - err = b.diskMounter.FormatAndMount(mntDevice, deviceMountPath, b.fsType, options) - if err != nil { - os.Remove(deviceMountPath) - return err - } - } - return err -} - -// Unmount removes the mount reference from the volume allowing it to be -// re-mounted elsewhere. -func (u *storageosUtil) UnmountVolume(b *storageosUnmounter) error { - - klog.V(4).Infof("clearing StorageOS mount reference for volume %q with namespace %q", b.volName, b.volNamespace) - - if err := u.NewAPI(b.apiCfg); err != nil { - // We can't always get the config we need, so allow the unmount to - // succeed even if we can't remove the mount reference from the API. - klog.Warningf("could not remove mount reference in the StorageOS API as no credentials available to the unmount operation") - return nil - } - - opts := storageostypes.VolumeUnmountOptions{ - Name: b.volName, - Namespace: b.volNamespace, - Client: b.plugin.host.GetHostName(), - } - return u.api.VolumeUnmount(opts) -} - -// Deletes a StorageOS volume. Assumes it has already been unmounted and detached. -func (u *storageosUtil) DeleteVolume(d *storageosDeleter) error { - if err := u.NewAPI(d.apiCfg); err != nil { - return err - } - - // Deletes must be forced as the StorageOS API will not normally delete - // volumes that it thinks are mounted. We can't be sure the unmount was - // registered via the API so we trust k8s to only delete volumes it knows - // are unmounted. - opts := storageostypes.DeleteOptions{ - Name: d.volName, - Namespace: d.volNamespace, - Force: true, - } - if err := u.api.VolumeDelete(opts); err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("volume deleted failed for volume %q in namespace %q: %v", d.volName, d.volNamespace, err) - return errors.New("volume delete failed: see kube-controller-manager.log for details") - } - return nil -} - -// Get the node's device path from the API, falling back to the default if not -// specified. -func (u *storageosUtil) DeviceDir(b *storageosMounter) string { - - ctrl, err := u.api.Node(b.plugin.host.GetHostName()) - if err != nil { - klog.Warningf("node device path lookup failed: %v", err) - return defaultDeviceDir - } - if ctrl == nil || ctrl.DeviceDir == "" { - klog.Warningf("node device path not set, using default: %s", defaultDeviceDir) - return defaultDeviceDir - } - return ctrl.DeviceDir -} - -// pathMode returns the FileMode for a path. -func pathDeviceType(path string) (deviceType, error) { - fi, err := os.Stat(path) - if err != nil { - return modeUnsupported, err - } - switch mode := fi.Mode(); { - case mode&os.ModeDevice != 0: - return modeBlock, nil - case mode.IsRegular(): - return modeFile, nil - default: - return modeUnsupported, nil - } -} - -// attachFileDevice takes a path to a regular file and makes it available as an -// attached block device. -func attachFileDevice(path string, exec utilexec.Interface) (string, error) { - blockDevicePath, err := getLoopDevice(path) - if err != nil && err.Error() != ErrDeviceNotFound { - return "", err - } - - // If no existing loop device for the path, create one - if blockDevicePath == "" { - klog.V(4).Infof("Creating device for path: %s", path) - blockDevicePath, err = makeLoopDevice(path, exec) - if err != nil { - return "", err - } - } - return blockDevicePath, nil -} - -// Returns the full path to the loop device associated with the given path. -func getLoopDevice(path string) (string, error) { - _, err := os.Stat(path) - if os.IsNotExist(err) { - return "", errors.New(ErrNotAvailable) - } - if err != nil { - return "", fmt.Errorf("not attachable: %v", err) - } - - return getLoopDeviceFromSysfs(path) -} - -func makeLoopDevice(path string, exec utilexec.Interface) (string, error) { - args := []string{"-f", "-P", path} - out, err := exec.Command(losetupPath, args...).CombinedOutput() - if err != nil { - klog.V(2).Infof("Failed device create command for path %s: %v %s", path, err, out) - return "", err - } - - return getLoopDeviceFromSysfs(path) -} - -func removeLoopDevice(device string, exec utilexec.Interface) error { - args := []string{"-d", device} - out, err := exec.Command(losetupPath, args...).CombinedOutput() - if err != nil { - if !strings.Contains(string(out), "No such device or address") { - return err - } - } - return nil -} - -func isLoopDevice(device string) bool { - return strings.HasPrefix(device, "/dev/loop") -} - -// getLoopDeviceFromSysfs finds the backing file for a loop -// device from sysfs via "/sys/block/loop*/loop/backing_file". -func getLoopDeviceFromSysfs(path string) (string, error) { - // If the file is a symlink. - realPath, err := filepath.EvalSymlinks(path) - if err != nil { - return "", errors.New(ErrDeviceNotFound) - } - - devices, err := filepath.Glob("/sys/block/loop*") - if err != nil { - return "", errors.New(ErrDeviceNotFound) - } - - for _, device := range devices { - backingFile := fmt.Sprintf("%s/loop/backing_file", device) - - // The contents of this file is the absolute path of "path". - data, err := ioutil.ReadFile(backingFile) - if err != nil { - continue - } - - // Return the first match. - backingFilePath := strings.TrimSpace(string(data)) - if backingFilePath == path || backingFilePath == realPath { - return fmt.Sprintf("/dev/%s", filepath.Base(device)), nil - } - } - - return "", errors.New(ErrDeviceNotFound) -} diff --git a/pkg/volume/storageos/storageos_util_test.go b/pkg/volume/storageos/storageos_util_test.go deleted file mode 100644 index 7e375d89856..00000000000 --- a/pkg/volume/storageos/storageos_util_test.go +++ /dev/null @@ -1,225 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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 storageos - -import ( - "fmt" - "os" - "testing" - - storageostypes "github.com/storageos/go-api/types" - "k8s.io/mount-utils" - - v1 "k8s.io/api/core/v1" - utiltesting "k8s.io/client-go/util/testing" - "k8s.io/kubernetes/pkg/volume" - volumetest "k8s.io/kubernetes/pkg/volume/testing" -) - -var testVolName = "storageos-test-vol" -var testPVName = "storageos-test-pv" -var testNamespace = "storageos-test-namespace" -var testSize = 1 -var testDesc = "testdescription" -var testPool = "testpool" -var testFSType = "ext2" -var testVolUUID = "01c43d34-89f8-83d3-422b-43536a0f25e6" - -func GetAPIConfig() *storageosAPIConfig { - return &storageosAPIConfig{ - apiAddr: "http://5.6.7.8:9999", - apiUser: "abc", - apiPass: "123", - apiVersion: "10", - } -} - -func TestClient(t *testing.T) { - tmpDir, err := utiltesting.MkTmpdir("storageos_test") - if err != nil { - t.Fatalf("error creating tmpdir: %v", err) - } - util := storageosUtil{host: volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)} - err = util.NewAPI(GetAPIConfig()) - if err != nil { - t.Fatalf("error getting api config: %v", err) - } - if util.api == nil { - t.Errorf("client() unexpectedly returned nil") - } -} - -type fakeAPI struct{} - -func (f fakeAPI) Volume(namespace string, ref string) (*storageostypes.Volume, error) { - if namespace == testNamespace && ref == testVolName { - return &storageostypes.Volume{ - ID: "01c43d34-89f8-83d3-422b-43536a0f25e6", - Name: ref, - Pool: "default", - Namespace: namespace, - Size: 5, - }, nil - } - return nil, fmt.Errorf("not found") -} -func (f fakeAPI) VolumeCreate(opts storageostypes.VolumeCreateOptions) (*storageostypes.Volume, error) { - - // Append a label from the api - labels := opts.Labels - labels["labelfromapi"] = "apilabel" - - return &storageostypes.Volume{ - ID: testVolUUID, - Name: opts.Name, - Namespace: opts.Namespace, - Description: opts.Description, - Pool: opts.Pool, - Size: opts.Size, - FSType: opts.FSType, - Labels: labels, - }, nil -} -func (f fakeAPI) VolumeMount(opts storageostypes.VolumeMountOptions) error { - return nil -} -func (f fakeAPI) VolumeUnmount(opts storageostypes.VolumeUnmountOptions) error { - return nil -} -func (f fakeAPI) VolumeDelete(opts storageostypes.DeleteOptions) error { - return nil -} -func (f fakeAPI) Node(ref string) (*storageostypes.Node, error) { - return &storageostypes.Node{}, nil -} - -func TestCreateVolume(t *testing.T) { - - tmpDir, err := utiltesting.MkTmpdir("storageos_test") - if err != nil { - t.Fatalf("can't make a temp dir: %v", err) - } - defer os.RemoveAll(tmpDir) - plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)) - plug, _ := plugMgr.FindPluginByName("kubernetes.io/storageos") - - // Use real util with stubbed api - util := &storageosUtil{} - util.api = fakeAPI{} - - labels := map[string]string{ - "labelA": "valueA", - "labelB": "valueB", - } - - options := volume.VolumeOptions{ - PVName: testPVName, - PVC: volumetest.CreateTestPVC(fmt.Sprintf("%dGi", testSize), []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}), - PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete, - } - - provisioner := &storageosProvisioner{ - storageosMounter: &storageosMounter{ - storageos: &storageos{ - pvName: testPVName, - volName: testVolName, - volNamespace: testNamespace, - sizeGB: testSize, - pool: testPool, - description: testDesc, - fsType: testFSType, - labels: labels, - manager: util, - plugin: plug.(*storageosPlugin), - }, - }, - options: options, - } - - vol, err := util.CreateVolume(provisioner) - if err != nil { - t.Errorf("CreateVolume() returned error: %v", err) - } - if vol == nil { - t.Fatalf("CreateVolume() vol is empty") - } - if vol.ID == "" { - t.Error("CreateVolume() vol ID is empty") - } - if vol.Name != testVolName { - t.Errorf("CreateVolume() returned unexpected Name %s", vol.Name) - } - if vol.Namespace != testNamespace { - t.Errorf("CreateVolume() returned unexpected Namespace %s", vol.Namespace) - } - if vol.Pool != testPool { - t.Errorf("CreateVolume() returned unexpected Pool %s", vol.Pool) - } - if vol.FSType != testFSType { - t.Errorf("CreateVolume() returned unexpected FSType %s", vol.FSType) - } - if vol.SizeGB != testSize { - t.Errorf("CreateVolume() returned unexpected Size %d", vol.SizeGB) - } - if len(vol.Labels) == 0 { - t.Error("CreateVolume() Labels are empty") - } else { - var val string - var ok bool - for k, v := range labels { - if val, ok = vol.Labels[k]; !ok { - t.Errorf("CreateVolume() Label %s not set", k) - } - if val != v { - t.Errorf("CreateVolume() returned unexpected Label value %s", val) - } - } - if val, ok = vol.Labels["labelfromapi"]; !ok { - t.Error("CreateVolume() Label from api not set") - } - if val != "apilabel" { - t.Errorf("CreateVolume() returned unexpected Label value %s", val) - } - } -} - -func TestAttachVolume(t *testing.T) { - tmpDir, err := utiltesting.MkTmpdir("storageos_test") - if err != nil { - t.Fatalf("can't make a temp dir: %v", err) - } - defer os.RemoveAll(tmpDir) - plugMgr := volume.VolumePluginMgr{} - plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil)) - plug, _ := plugMgr.FindPluginByName("kubernetes.io/storageos") - - // Use real util with stubbed api - util := &storageosUtil{} - util.api = fakeAPI{} - - _ = &storageosMounter{ - storageos: &storageos{ - volName: testVolName, - volNamespace: testNamespace, - manager: util, - mounter: mount.NewFakeMounter(nil), - plugin: plug.(*storageosPlugin), - }, - deviceDir: tmpDir, - } -} diff --git a/vendor/github.com/storageos/go-api/.gitignore b/vendor/github.com/storageos/go-api/.gitignore deleted file mode 100644 index daf913b1b34..00000000000 --- a/vendor/github.com/storageos/go-api/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/storageos/go-api/LICENCE b/vendor/github.com/storageos/go-api/LICENCE deleted file mode 100644 index c577408a6dc..00000000000 --- a/vendor/github.com/storageos/go-api/LICENCE +++ /dev/null @@ -1,45 +0,0 @@ -MIT License - -Copyright (c) 2015-2018 StorageOS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -Copyright (c) 2013-2017, go-dockerclient authors -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/storageos/go-api/README.md b/vendor/github.com/storageos/go-api/README.md deleted file mode 100644 index 15ebd60eb05..00000000000 --- a/vendor/github.com/storageos/go-api/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# StorageOS API client library - -## Swagger Spec -Swagger specification for this repo is available in the [StorageOS public documentation](https://github.com/storageos/storageos.github.io/blob/master/swagger.yaml). - diff --git a/vendor/github.com/storageos/go-api/client.go b/vendor/github.com/storageos/go-api/client.go deleted file mode 100644 index 1a6dc0dcde4..00000000000 --- a/vendor/github.com/storageos/go-api/client.go +++ /dev/null @@ -1,612 +0,0 @@ -package storageos - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "math/rand" - "net" - "net/http" - "net/url" - "reflect" - "strconv" - "strings" - "sync" - "time" - - "github.com/storageos/go-api/netutil" - "github.com/storageos/go-api/serror" -) - -const ( - // DefaultUserAgent is the default User-Agent header to include in HTTP requests. - DefaultUserAgent = "go-storageosclient" - // DefaultVersionStr is the string value of the default API version. - DefaultVersionStr = "1" - // DefaultVersion is the default API version. - DefaultVersion = 1 -) - -var ( - // ErrConnectionRefused is returned when the client cannot connect to the given endpoint. - ErrConnectionRefused = errors.New("cannot connect to StorageOS API endpoint") - - // ErrInactivityTimeout is returned when a streamable call has been inactive for some time. - ErrInactivityTimeout = errors.New("inactivity time exceeded timeout") - - // ErrInvalidVersion is returned when a versioned client was requested but no version specified. - ErrInvalidVersion = errors.New("invalid version") - - // ErrProxyNotSupported is returned when a client is unable to set a proxy for http requests. - ErrProxyNotSupported = errors.New("client does not support http proxy") - - // ErrDialerNotSupported is returned when a client is unable to set a DialContext for http requests. - ErrDialerNotSupported = errors.New("client does not support setting DialContext") - - // DefaultPort is the default API port. - DefaultPort = "5705" - - // DataplaneHealthPort is the the port used by the dataplane health-check service. - DataplaneHealthPort = "5704" - - // DefaultHost is the default API host. - DefaultHost = "http://localhost:" + DefaultPort -) - -// APIVersion is an internal representation of a version of the Remote API. -type APIVersion int - -// NewAPIVersion returns an instance of APIVersion for the given string. -// -// The given string must be in the form -func NewAPIVersion(input string) (APIVersion, error) { - if input == "" { - return DefaultVersion, ErrInvalidVersion - } - version, err := strconv.Atoi(input) - if err != nil { - return 0, fmt.Errorf("Unable to parse version %q", input) - } - return APIVersion(version), nil -} - -func (version APIVersion) String() string { - return fmt.Sprintf("v%d", version) -} - -// Client is the basic type of this package. It provides methods for -// interaction with the API. -type Client struct { - httpClient *http.Client - - addresses []string - username string - secret string - userAgent string - - configLock *sync.RWMutex // Lock for config changes - addressLock *sync.Mutex // Lock used to copy/update the address slice - - requestedAPIVersion APIVersion - serverAPIVersion APIVersion - expectedAPIVersion APIVersion - - SkipServerVersionCheck bool -} - -// ClientVersion returns the API version of the client -func (c *Client) ClientVersion() string { - return DefaultVersionStr -} - -// Dialer is an interface that allows network connections to be dialed -// (net.Dialer fulfills this interface) and named pipes (a shim using -// winio.DialPipe) -type Dialer interface { - Dial(network, address string) (net.Conn, error) -} - -type dialContext = func(ctx context.Context, network, address string) (net.Conn, error) - -// NewClient returns a Client instance ready for communication with the given -// server endpoint. It will use the latest remote API version available in the -// server. -func NewClient(nodes string) (*Client, error) { - client, err := NewVersionedClient(nodes, "") - if err != nil { - return nil, err - } - client.SkipServerVersionCheck = true - client.userAgent = DefaultUserAgent - return client, nil -} - -// NewVersionedClient returns a Client instance ready for communication with -// the given server endpoint, using a specific remote API version. -func NewVersionedClient(nodestring string, apiVersionString string) (*Client, error) { - nodes := strings.Split(nodestring, ",") - addresses, err := netutil.AddressesFromNodes(nodes) - if err != nil { - return nil, err - } - - if len(addresses) > 1 { - // Shuffle returned addresses in attempt to spread the load - rnd := rand.New(rand.NewSource(time.Now().UnixNano())) - rnd.Shuffle(len(addresses), func(i, j int) { - addresses[i], addresses[j] = addresses[j], addresses[i] - }) - } - - client := &Client{ - httpClient: defaultClient(), - addresses: addresses, - configLock: &sync.RWMutex{}, - addressLock: &sync.Mutex{}, - } - - if apiVersionString != "" { - version, err := strconv.Atoi(apiVersionString) - if err != nil { - return nil, err - } - client.requestedAPIVersion = APIVersion(version) - } - - return client, nil -} - -// SetUserAgent sets the client useragent. -func (c *Client) SetUserAgent(useragent string) { - c.configLock.Lock() - defer c.configLock.Unlock() - c.userAgent = useragent -} - -// SetAuth sets the API username and secret to be used for all API requests. -// It should not be called concurrently with any other Client methods. -func (c *Client) SetAuth(username string, secret string) { - c.configLock.Lock() - defer c.configLock.Unlock() - if username != "" { - c.username = username - } - if secret != "" { - c.secret = secret - } -} - -// SetProxy will set the proxy URL for both the HTTPClient. -// If the transport method does not support usage -// of proxies, an error will be returned. -func (c *Client) SetProxy(proxy *url.URL) error { - c.configLock.Lock() - defer c.configLock.Unlock() - - if client := c.httpClient; client != nil { - transport, supported := client.Transport.(*http.Transport) - if !supported { - return ErrProxyNotSupported - } - transport.Proxy = http.ProxyURL(proxy) - } - return nil -} - -// SetTimeout takes a timeout and applies it to both the HTTPClient and -// nativeHTTPClient. It should not be called concurrently with any other Client -// methods. -func (c *Client) SetTimeout(t time.Duration) { - c.configLock.Lock() - defer c.configLock.Unlock() - if c.httpClient != nil { - c.httpClient.Timeout = t - } -} - -// GetDialContext returns the current DialContext function, or nil if there is none. -func (c *Client) GetDialContext() dialContext { - c.configLock.RLock() - defer c.configLock.RUnlock() - - if c.httpClient == nil { - return nil - } - transport, supported := c.httpClient.Transport.(*http.Transport) - if !supported { - return nil - } - return transport.DialContext -} - -// SetDialContext uses the given dial function to establish TCP connections in the HTTPClient. -func (c *Client) SetDialContext(dial dialContext) error { - c.configLock.Lock() - defer c.configLock.Unlock() - - if client := c.httpClient; client != nil { - transport, supported := client.Transport.(*http.Transport) - if !supported { - return ErrDialerNotSupported - } - transport.DialContext = dial - } - return nil -} - -func (c *Client) checkAPIVersion() error { - serverAPIVersionString, err := c.getServerAPIVersionString() - if err != nil { - return err - } - c.serverAPIVersion, err = NewAPIVersion(serverAPIVersionString) - if err != nil { - return err - } - c.configLock.Lock() - defer c.configLock.Unlock() - if c.requestedAPIVersion == 0 { - c.expectedAPIVersion = c.serverAPIVersion - } else { - c.expectedAPIVersion = c.requestedAPIVersion - } - return nil -} - -// Ping pings the API server -// -// See https://goo.gl/wYfgY1 for more details. -func (c *Client) Ping() error { - urlpath := "/_ping" - resp, err := c.do("GET", urlpath, doOptions{}) - if err != nil { - return err - } - if resp.StatusCode != http.StatusOK { - return newError(resp) - } - return resp.Body.Close() -} - -func (c *Client) getServerAPIVersionString() (version string, err error) { - v, err := c.ServerVersion(context.Background()) - if err != nil { - return "", err - } - return v.APIVersion, nil -} - -type doOptions struct { - context context.Context - data interface{} - - values url.Values - headers map[string]string - - fieldSelector string - labelSelector string - namespace string - - forceJSON bool - force bool - unversioned bool - - retryOn []int // http.status codes -} - -func (c *Client) do(method, urlpath string, doOptions doOptions) (*http.Response, error) { - var params io.Reader - if doOptions.data != nil || doOptions.forceJSON { - buf, err := json.Marshal(doOptions.data) - if err != nil { - return nil, err - } - params = bytes.NewBuffer(buf) - } - - // Prefix the path with the namespace if given. The caller should only set - // the namespace if this is desired. - if doOptions.namespace != "" { - urlpath = "/" + NamespaceAPIPrefix + "/" + doOptions.namespace + "/" + urlpath - } - - if !c.SkipServerVersionCheck && !doOptions.unversioned { - err := c.checkAPIVersion() - if err != nil { - return nil, err - } - } - - query := url.Values{} - if doOptions.values != nil { - query = doOptions.values - } - if doOptions.force { - query.Add("force", "1") - } - - // Obtain a reader lock to prevent the http client from being - // modified underneath us during a do(). - c.configLock.RLock() - defer c.configLock.RUnlock() // This defer matches both the initial and the above lock - - httpClient := c.httpClient - endpoint := c.getAPIPath(urlpath, query, doOptions.unversioned) - - // The doOptions Context is shared for every attempted request in the do. - ctx := doOptions.context - if ctx == nil { - ctx = context.Background() - } - - var failedAddresses = map[string]struct{}{} - - c.addressLock.Lock() - var addresses = make([]string, len(c.addresses)) - copy(addresses, c.addresses) - c.addressLock.Unlock() - - for _, address := range addresses { - target := address + endpoint - - req, err := http.NewRequest(method, target, params) - if err != nil { - // Probably should not try and continue if we're unable - // to create the request. - return nil, err - } - req.Header.Set("User-Agent", c.userAgent) - if doOptions.data != nil { - req.Header.Set("Content-Type", "application/json") - } else if method == "POST" { - req.Header.Set("Content-Type", "plain/text") - } - if c.username != "" && c.secret != "" { - req.SetBasicAuth(c.username, c.secret) - } - - for k, v := range doOptions.headers { - req.Header.Set(k, v) - } - - resp, err := httpClient.Do(req.WithContext(ctx)) - if err != nil { - - // If it is a custom error, return it. It probably knows more than us - if serror.IsStorageOSError(err) { - switch serror.ErrorKind(err) { - case serror.APIUncontactable: - // If API isn't contactable we should try the next address - failedAddresses[address] = struct{}{} - continue - case serror.InvalidHostConfig: - // If invalid host or unknown error, we should report back - fallthrough - case serror.UnknownError: - return nil, err - } - } - - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - if _, ok := err.(net.Error); ok { - // Be optimistic and try the next endpoint - failedAddresses[address] = struct{}{} - continue - } - return nil, err - } - } - - var shouldretry bool - if doOptions.retryOn != nil { - for _, code := range doOptions.retryOn { - if resp.StatusCode == code { - failedAddresses[address] = struct{}{} - shouldretry = true - } - - } - } - - // If we get to the point of response, we should move any failed - // addresses to the back. - failed := len(failedAddresses) - if failed > 0 { - // Copy addresses we think are okay into the head of the list - newOrder := make([]string, 0, len(addresses)-failed) - - for _, addr := range addresses { - if _, exists := failedAddresses[addr]; !exists { - newOrder = append(newOrder, addr) - } - } - for addr := range failedAddresses { - newOrder = append(newOrder, addr) - } - - c.addressLock.Lock() - // Bring in the new order - c.addresses = newOrder - c.addressLock.Unlock() - } - - if shouldretry { - continue - } - - if resp.StatusCode < 200 || resp.StatusCode >= 400 { - return nil, newError(resp) // These status codes are likely to be fatal - } - return resp, nil - } - - return nil, netutil.ErrAllFailed(addresses) -} - -func (c *Client) getAPIPath(path string, query url.Values, unversioned bool) string { - var apiPath = strings.TrimLeft(path, "/") - - if !unversioned { - apiPath = fmt.Sprintf("/%s/%s", c.requestedAPIVersion, apiPath) - } else { - apiPath = fmt.Sprintf("/%s", apiPath) - } - - if len(query) > 0 { - apiPath = apiPath + "?" + query.Encode() - } - - return apiPath -} - -func queryString(opts interface{}) string { - if opts == nil { - return "" - } - value := reflect.ValueOf(opts) - if value.Kind() == reflect.Ptr { - value = value.Elem() - } - if value.Kind() != reflect.Struct { - return "" - } - items := url.Values(map[string][]string{}) - for i := 0; i < value.NumField(); i++ { - field := value.Type().Field(i) - if field.PkgPath != "" { - continue - } - key := field.Tag.Get("qs") - if key == "" { - key = strings.ToLower(field.Name) - } else if key == "-" { - continue - } - addQueryStringValue(items, key, value.Field(i)) - } - return items.Encode() -} - -func addQueryStringValue(items url.Values, key string, v reflect.Value) { - switch v.Kind() { - case reflect.Bool: - if v.Bool() { - items.Add(key, "1") - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if v.Int() > 0 { - items.Add(key, strconv.FormatInt(v.Int(), 10)) - } - case reflect.Float32, reflect.Float64: - if v.Float() > 0 { - items.Add(key, strconv.FormatFloat(v.Float(), 'f', -1, 64)) - } - case reflect.String: - if v.String() != "" { - items.Add(key, v.String()) - } - case reflect.Ptr: - if !v.IsNil() { - if b, err := json.Marshal(v.Interface()); err == nil { - items.Add(key, string(b)) - } - } - case reflect.Map: - if len(v.MapKeys()) > 0 { - if b, err := json.Marshal(v.Interface()); err == nil { - items.Add(key, string(b)) - } - } - case reflect.Array, reflect.Slice: - vLen := v.Len() - if vLen > 0 { - for i := 0; i < vLen; i++ { - addQueryStringValue(items, key, v.Index(i)) - } - } - } -} - -// Error represents failures in the API. It represents a failure from the API. -type Error struct { - Status int - Message string -} - -func newError(resp *http.Response) *Error { - type jsonError struct { - Message string `json:"message"` - } - - defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - return &Error{Status: resp.StatusCode, Message: fmt.Sprintf("cannot read body, err: %v", err)} - } - - // attempt to unmarshal the error if in json format - jerr := &jsonError{} - err = json.Unmarshal(data, jerr) - if err != nil { - return &Error{Status: resp.StatusCode, Message: string(data)} // Failed, just return string - } - - return &Error{Status: resp.StatusCode, Message: jerr.Message} -} - -func (e *Error) Error() string { - var niceStatus string - - switch e.Status { - case 400, 500: - niceStatus = "Server failed to process your request. Was the data correct?" - case 401: - niceStatus = "Unauthenticated access of secure endpoint, please retry after authentication" - case 403: - niceStatus = "Forbidden request. Your user cannot perform this action" - case 404: - niceStatus = "Requested object not found. Does this item exist?" - } - - if niceStatus != "" { - return fmt.Sprintf("API error (%s): %s", niceStatus, e.Message) - } - return fmt.Sprintf("API error (%s): %s", http.StatusText(e.Status), e.Message) -} - -// defaultPooledTransport returns a new http.Transport with similar default -// values to http.DefaultTransport. Do not use this for transient transports as -// it can leak file descriptors over time. Only use this for transports that -// will be re-used for the same host(s). -func defaultPooledTransport(dialer Dialer) *http.Transport { - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: dialer.Dial, - TLSHandshakeTimeout: 5 * time.Second, - DisableKeepAlives: false, - MaxIdleConnsPerHost: 1, - } - return transport -} - -// defaultClient returns a new http.Client with similar default values to -// http.Client, but with a non-shared Transport, idle connections disabled, and -// keepalives disabled. -// If a custom dialer is not provided, one with sane defaults will be created. -func defaultClient() *http.Client { - dialer := &net.Dialer{ - Timeout: 5 * time.Second, - KeepAlive: 5 * time.Second, - } - - return &http.Client{ - Transport: defaultPooledTransport(dialer), - } -} diff --git a/vendor/github.com/storageos/go-api/cluster.go b/vendor/github.com/storageos/go-api/cluster.go deleted file mode 100644 index 1ba6f86451d..00000000000 --- a/vendor/github.com/storageos/go-api/cluster.go +++ /dev/null @@ -1,48 +0,0 @@ -package storageos - -import ( - "encoding/json" - - "github.com/storageos/go-api/types" -) - -var ( - // ClusterMaintenanceAPIPrefix is a path to the HTTP endpoint for managing - // the cluster maintenance mode. - ClusterMaintenanceAPIPrefix = "cluster/maintenance" -) - -// Maintenance returns the maintenance status of the cluster -func (c *Client) Maintenance() (*types.Maintenance, error) { - resp, err := c.do("GET", ClusterMaintenanceAPIPrefix, doOptions{}) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - res := &types.Maintenance{} - if err := json.NewDecoder(resp.Body).Decode(res); err != nil { - return nil, err - } - return res, nil -} - -// EnableMaintenance enables maintenance mode in the cluster -func (c *Client) EnableMaintenance() error { - resp, err := c.do("POST", ClusterMaintenanceAPIPrefix, doOptions{}) - if err != nil { - return err - } - defer resp.Body.Close() - return nil -} - -// DisableMaintenance disables maintenance mode in the cluster -func (c *Client) DisableMaintenance() error { - resp, err := c.do("DELETE", ClusterMaintenanceAPIPrefix, doOptions{}) - if err != nil { - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/health.go b/vendor/github.com/storageos/go-api/health.go deleted file mode 100644 index b1acd5db890..00000000000 --- a/vendor/github.com/storageos/go-api/health.go +++ /dev/null @@ -1,91 +0,0 @@ -package storageos - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/storageos/go-api/types" -) - -var ( - // HealthAPIPrefix is a partial path to the HTTP endpoint. - HealthAPIPrefix = "health" -) - -func (c *Client) ClusterHealth(ctx context.Context) ([]*types.ClusterHealthNode, error) { - status := []*types.ClusterHealthNode{} - url := fmt.Sprintf("/cluster/%s", HealthAPIPrefix) - - resp, err := c.do("GET", url, doOptions{context: ctx, retryOn: []int{http.StatusNotFound}}) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if err := json.NewDecoder(resp.Body).Decode(&status); err != nil { - return nil, err - } - return status, nil -} - -// CPHealth returns the health of the control plane server at a given url. -func (c *Client) CPHealth(ctx context.Context, hostname string) (*types.CPHealthStatus, error) { - - url := fmt.Sprintf("http://%s:%s/v1/%s", hostname, DefaultPort, HealthAPIPrefix) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - req.Header.Set("User-Agent", c.userAgent) - if c.username != "" && c.secret != "" { - req.SetBasicAuth(c.username, c.secret) - } - - c.configLock.RLock() - resp, err := c.httpClient.Do(req.WithContext(ctx)) - c.configLock.RUnlock() - if err != nil { - return nil, err - } - defer resp.Body.Close() - - var status *types.CPHealthStatus - if err := json.NewDecoder(resp.Body).Decode(&status); err != nil { - return nil, err - } - - return status, nil -} - -// DPHealth returns the health of the data plane server at a given url. -func (c *Client) DPHealth(ctx context.Context, hostname string) (*types.DPHealthStatus, error) { - - url := fmt.Sprintf("http://%s:%s/v1/%s", hostname, DataplaneHealthPort, HealthAPIPrefix) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - req.Header.Set("User-Agent", c.userAgent) - if c.username != "" && c.secret != "" { - req.SetBasicAuth(c.username, c.secret) - } - - c.configLock.RLock() - resp, err := c.httpClient.Do(req.WithContext(ctx)) - c.configLock.RUnlock() - if err != nil { - return nil, err - } - defer resp.Body.Close() - - var status *types.DPHealthStatus - if err := json.NewDecoder(resp.Body).Decode(&status); err != nil { - return nil, err - } - - return status, nil -} diff --git a/vendor/github.com/storageos/go-api/licence.go b/vendor/github.com/storageos/go-api/licence.go deleted file mode 100644 index 425d97462cd..00000000000 --- a/vendor/github.com/storageos/go-api/licence.go +++ /dev/null @@ -1,43 +0,0 @@ -package storageos - -import ( - "encoding/json" - - "github.com/storageos/go-api/types" -) - -const ( - // licenceAPIPrefix is a partial path to the HTTP endpoint. - licenceAPIPrefix = "licencing" -) - -// Licence returns the current licence on the server. -func (c *Client) Licence() (*types.Licence, error) { - resp, err := c.do("GET", licenceAPIPrefix, doOptions{}) - if err != nil { - return nil, err - } - defer resp.Body.Close() - licence := &types.Licence{} - if err := json.NewDecoder(resp.Body).Decode(&licence); err != nil { - return nil, err - } - return licence, nil -} - -// LicenceApply applies a licence on the server. -func (c *Client) LicenceApply(licenceKey string) error { - _, err := c.do("POST", licenceAPIPrefix, doOptions{ - data: &types.LicenceKeyContainer{Key: licenceKey}, - }) - return err -} - -// LicenceDelete removes the current licence. -func (c *Client) LicenceDelete() error { - resp, err := c.do("DELETE", licenceAPIPrefix, doOptions{}) - if err != nil { - return err - } - return resp.Body.Close() -} diff --git a/vendor/github.com/storageos/go-api/logger.go b/vendor/github.com/storageos/go-api/logger.go deleted file mode 100644 index 6db81231263..00000000000 --- a/vendor/github.com/storageos/go-api/logger.go +++ /dev/null @@ -1,62 +0,0 @@ -package storageos - -import ( - "context" - "encoding/json" - "net/url" - - "github.com/storageos/go-api/types" -) - -var ( - // LoggerAPIPrefix is a partial path to the HTTP endpoint. - LoggerAPIPrefix = "logs" -) - -// LoggerConfig returns every cluster node's logging configuration. -func (c *Client) LoggerConfig(opts types.ListOptions) ([]*types.Logger, error) { - - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - context: opts.Context, - } - - if opts.LabelSelector != "" { - query := url.Values{} - query.Add("labelSelector", opts.LabelSelector) - listOpts.values = query - } - - resp, err := c.do("GET", LoggerAPIPrefix+"/cluster/config", listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var loggers []*types.Logger - if err := json.NewDecoder(resp.Body).Decode(&loggers); err != nil { - return nil, err - } - return loggers, nil - -} - -// LoggerUpdate patches updates to logging configuration. Fields to update must -// be listed in the Fields value, and if a list of Nodes is given it will only -// apply to the nodes listed. Returns the updated configuration. -func (c *Client) LoggerUpdate(opts types.LoggerUpdateOptions) ([]*types.Logger, error) { - - resp, err := c.do("PATCH", LoggerAPIPrefix+"/cluster/config", doOptions{ - data: opts, - context: context.Background(), - }) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var loggers []*types.Logger - if err := json.NewDecoder(resp.Body).Decode(&loggers); err != nil { - return nil, err - } - return loggers, nil -} diff --git a/vendor/github.com/storageos/go-api/login.go b/vendor/github.com/storageos/go-api/login.go deleted file mode 100644 index 371a31ec756..00000000000 --- a/vendor/github.com/storageos/go-api/login.go +++ /dev/null @@ -1,47 +0,0 @@ -package storageos - -import ( - "encoding/json" - "errors" -) - -var ( - // LoginAPIPrefix is a partial path to the HTTP endpoint. - LoginAPIPrefix = "auth/login" - // ErrLoginFailed is the error returned on an unsuccessful login. - ErrLoginFailed = errors.New("failed to get token from API endpoint") -) - -// Login attemps to get a token from the API -func (c *Client) Login() (token string, err error) { - resp, err := c.do("POST", LoginAPIPrefix, doOptions{data: struct { - User string `json:"username"` - Pass string `json:"password"` - }{c.username, c.secret}}) - - if err != nil { - if _, ok := err.(*Error); ok { - return "", ErrLoginFailed - } - - return "", err - } - - if resp.StatusCode != 200 { - return "", ErrLoginFailed - } - - unmarsh := struct { - Token string `json:"token"` - }{} - - if err := json.NewDecoder(resp.Body).Decode(&unmarsh); err != nil { - return "", err - } - - if unmarsh.Token == "" { - return "", ErrLoginFailed - } - - return unmarsh.Token, nil -} diff --git a/vendor/github.com/storageos/go-api/namespace.go b/vendor/github.com/storageos/go-api/namespace.go deleted file mode 100644 index 69fee1bc8ef..00000000000 --- a/vendor/github.com/storageos/go-api/namespace.go +++ /dev/null @@ -1,125 +0,0 @@ -package storageos - -import ( - "encoding/json" - "errors" - "net/http" - "net/url" - - "github.com/storageos/go-api/types" -) - -var ( - - // NamespaceAPIPrefix is a partial path to the HTTP endpoint. - NamespaceAPIPrefix = "namespaces" - - // ErrNoSuchNamespace is the error returned when the namespace does not exist. - ErrNoSuchNamespace = errors.New("no such namespace") - - // ErrNamespaceInUse is the error returned when the namespace requested to be removed is still in use. - ErrNamespaceInUse = errors.New("namespace in use and cannot be removed") -) - -// NamespaceList returns the list of available namespaces. -func (c *Client) NamespaceList(opts types.ListOptions) ([]*types.Namespace, error) { - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - namespace: opts.Namespace, - context: opts.Context, - } - - if opts.LabelSelector != "" { - query := url.Values{} - query.Add("labelSelector", opts.LabelSelector) - listOpts.values = query - } - - resp, err := c.do("GET", NamespaceAPIPrefix, listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var namespaces []*types.Namespace - if err := json.NewDecoder(resp.Body).Decode(&namespaces); err != nil { - return nil, err - } - return namespaces, nil -} - -// Namespace returns a namespace by its reference. -func (c *Client) Namespace(ref string) (*types.Namespace, error) { - resp, err := c.do("GET", NamespaceAPIPrefix+"/"+ref, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchNamespace - } - return nil, err - } - defer resp.Body.Close() - var namespace types.Namespace - if err := json.NewDecoder(resp.Body).Decode(&namespace); err != nil { - return nil, err - } - return &namespace, nil -} - -// NamespaceCreate creates a namespace on the server and returns the new object. -func (c *Client) NamespaceCreate(opts types.NamespaceCreateOptions) (*types.Namespace, error) { - resp, err := c.do("POST", NamespaceAPIPrefix, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - var namespace types.Namespace - if err := json.NewDecoder(resp.Body).Decode(&namespace); err != nil { - return nil, err - } - return &namespace, nil -} - -// NamespaceUpdate updates a namespace on the server and returns the updated object. -func (c *Client) NamespaceUpdate(opts types.NamespaceCreateOptions) (*types.Namespace, error) { - resp, err := c.do("PUT", NamespaceAPIPrefix+"/"+opts.Name, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - var namespace types.Namespace - if err := json.NewDecoder(resp.Body).Decode(&namespace); err != nil { - return nil, err - } - return &namespace, nil -} - -// NamespaceDelete removes a namespace by its reference. -func (c *Client) NamespaceDelete(opts types.DeleteOptions) error { - deleteOpts := doOptions{ - force: opts.Force, - context: opts.Context, - } - resp, err := c.do("DELETE", NamespaceAPIPrefix+"/"+opts.Name, deleteOpts) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchNamespace - } - if e.Status == http.StatusConflict { - return ErrNamespaceInUse - } - - // namespace can't be deleted yet, unless force is supplied - if e.Status == http.StatusPreconditionFailed { - return err - } - } - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/netutil/errors.go b/vendor/github.com/storageos/go-api/netutil/errors.go deleted file mode 100644 index f61980d08cb..00000000000 --- a/vendor/github.com/storageos/go-api/netutil/errors.go +++ /dev/null @@ -1,31 +0,0 @@ -package netutil - -import ( - "errors" - "fmt" - "strings" - - "github.com/storageos/go-api/serror" -) - -// ErrAllFailed produces a typed StorageOS error which should be used to indicate that -// the API is not contactable for all of the supplied node addresses. -func ErrAllFailed(addrs []string) error { - msg := fmt.Sprintf("failed to dial all known cluster members, (%s)", strings.Join(addrs, ",")) - help := "ensure that the value of $STORAGEOS_HOST (or the -H flag) is correct, and that there are healthy StorageOS nodes in this cluster" - - return serror.NewTypedStorageOSError(serror.APIUncontactable, nil, msg, help) -} - -func newInvalidNodeError(err error) error { - msg := fmt.Sprintf("invalid node format: %s", err) - help := "please check the format of $STORAGEOS_HOST (or the -H flag) complies with the StorageOS JOIN format" - - return serror.NewTypedStorageOSError(serror.InvalidHostConfig, err, msg, help) -} - -var ( - errUnsupportedScheme = errors.New("unsupported URL scheme") - errInvalidHostName = errors.New("invalid hostname") - errInvalidPortNumber = errors.New("invalid port number") -) diff --git a/vendor/github.com/storageos/go-api/netutil/netutil.go b/vendor/github.com/storageos/go-api/netutil/netutil.go deleted file mode 100644 index 7f9c550c46e..00000000000 --- a/vendor/github.com/storageos/go-api/netutil/netutil.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package netutil provides network related errors and helper functions. -package netutil - -// DefaultDialPort is the default port which the API is contacted on. -const DefaultDialPort = "5705" diff --git a/vendor/github.com/storageos/go-api/netutil/parsers.go b/vendor/github.com/storageos/go-api/netutil/parsers.go deleted file mode 100644 index 932c7795b80..00000000000 --- a/vendor/github.com/storageos/go-api/netutil/parsers.go +++ /dev/null @@ -1,84 +0,0 @@ -package netutil - -import ( - "net/url" - "strconv" - "strings" -) - -const ( - httpScheme = "http" - httpsScheme = "https" - tcpScheme = "tcp" -) - -// AddressesFromNodes takes a list of node hosts and attempts to return a list of hosts in host:port -// format along with any error encountered. -// -// The function accepts node hosts in URL, ip, ip:port, resolvable-name and resolvable-name:port -// formats and will append the default port value if needed. For hosts where the scheme has been omitted, -// the scheme for the first host will be used. If the first host has no scheme, it will default to http. -func AddressesFromNodes(nodes []string) ([]string, error) { - var addresses []string - - var scheme string - - for _, node := range nodes { - address := node - // If no scheme present, set the first scheme - if !strings.Contains(address, "://") { - if scheme == "" { - scheme = httpScheme - } - address = strings.Join([]string{scheme, address}, "://") - } - - url, err := url.Parse(address) - if err != nil { - return nil, newInvalidNodeError(err) - } - - switch url.Scheme { - case tcpScheme: - url.Scheme = httpScheme - fallthrough - case httpScheme, httpsScheme: - if scheme == "" { - scheme = url.Scheme - } - default: - return nil, newInvalidNodeError(errUnsupportedScheme) - } - - host := url.Hostname() - if host == "" { - return nil, newInvalidNodeError(errInvalidHostName) - } - - // Given input like "http://localhost:8080:8383", url.Parse() will - // return host as "localhost:8000", which isn't a vaild DNS name. - if strings.Contains(host, ":") { - return nil, newInvalidNodeError(errInvalidHostName) - } - - port := url.Port() - if port == "" { - port = DefaultDialPort - } - if !validPort(port) { - return nil, newInvalidNodeError(errInvalidPortNumber) - } - - addresses = append(addresses, strings.TrimRight(url.String(), "/")) - } - - return addresses, nil -} - -func validPort(port string) bool { - intPort, err := strconv.Atoi(port) - - return (err == nil) && - (intPort > 0) && - (intPort <= 65535) -} diff --git a/vendor/github.com/storageos/go-api/network_diagnostics.go b/vendor/github.com/storageos/go-api/network_diagnostics.go deleted file mode 100644 index 5d8a0bcc8f4..00000000000 --- a/vendor/github.com/storageos/go-api/network_diagnostics.go +++ /dev/null @@ -1,35 +0,0 @@ -package storageos - -import ( - "encoding/json" - "net/http" - "path" - - "github.com/storageos/go-api/types" -) - -var ( - // NetworkDiagnosticsAPIPrefix is a partial path to the HTTP endpoint for - // the node connectivity diagnostics report. - NetworkDiagnosticsAPIPrefix = "diagnostics/network" -) - -// NetworkDiagnostics returns a collection of network connectivity reports. If -// a reference to a node is given, it will only check connectivity from that -// node. Otherwise, connectivity between all cluster nodes will be returned. -func (c *Client) NetworkDiagnostics(ref string) (types.ConnectivityResults, error) { - resp, err := c.do("GET", path.Join(NetworkDiagnosticsAPIPrefix, ref), doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchNode - } - return nil, err - } - defer resp.Body.Close() - - var results types.ConnectivityResults - if err := json.NewDecoder(resp.Body).Decode(&results); err != nil { - return nil, err - } - return results, nil -} diff --git a/vendor/github.com/storageos/go-api/node.go b/vendor/github.com/storageos/go-api/node.go deleted file mode 100644 index 4188f582a4e..00000000000 --- a/vendor/github.com/storageos/go-api/node.go +++ /dev/null @@ -1,110 +0,0 @@ -package storageos - -import ( - "encoding/json" - "errors" - "net/http" - "net/url" - - "github.com/storageos/go-api/types" -) - -var ( - - // NodeAPIPrefix is a partial path to the HTTP endpoint. - NodeAPIPrefix = "nodes" - - // ErrNoSuchNode is the error returned when the node does not exist. - ErrNoSuchNode = errors.New("no such node") - - // ErrNodeInUse is the error returned when the node requested to be removed is still in use. - ErrNodeInUse = errors.New("node in use and cannot be removed") -) - -// NodeList returns the list of available nodes. -func (c *Client) NodeList(opts types.ListOptions) ([]*types.Node, error) { - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - context: opts.Context, - } - - if opts.LabelSelector != "" { - query := url.Values{} - query.Add("labelSelector", opts.LabelSelector) - listOpts.values = query - } - - resp, err := c.do("GET", NodeAPIPrefix, listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var nodes []*types.Node - if err := json.NewDecoder(resp.Body).Decode(&nodes); err != nil { - return nil, err - } - return nodes, nil -} - -// Node returns a node by its reference. -func (c *Client) Node(ref string) (*types.Node, error) { - - resp, err := c.do("GET", NodeAPIPrefix+"/"+ref, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchNode - } - return nil, err - } - defer resp.Body.Close() - var node types.Node - if err := json.NewDecoder(resp.Body).Decode(&node); err != nil { - return nil, err - } - return &node, nil -} - -// NodeUpdate updates a node on the server. -func (c *Client) NodeUpdate(opts types.NodeUpdateOptions) (*types.Node, error) { - ref := opts.Name - if IsUUID(opts.ID) { - ref = opts.ID - } - resp, err := c.do("PUT", NodeAPIPrefix+"/"+ref, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var node types.Node - if err := json.NewDecoder(resp.Body).Decode(&node); err != nil { - return nil, err - } - return &node, nil -} - -// NodeDelete removes a node by its reference. -func (c *Client) NodeDelete(opts types.DeleteOptions) error { - deleteOpts := doOptions{ - namespace: opts.Namespace, - force: opts.Force, - context: opts.Context, - } - resp, err := c.do("DELETE", NodeAPIPrefix+"/"+opts.Name, deleteOpts) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchNode - } - if e.Status == http.StatusConflict { - return ErrNodeInUse - } - } - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/policy.go b/vendor/github.com/storageos/go-api/policy.go deleted file mode 100644 index f5c1a050df7..00000000000 --- a/vendor/github.com/storageos/go-api/policy.go +++ /dev/null @@ -1,102 +0,0 @@ -package storageos - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "net/url" - - "github.com/storageos/go-api/types" -) - -var ( - // PolicyAPIPrefix is a partial path to the HTTP endpoint. - PolicyAPIPrefix = "policies" - // ErrNoSuchPolicy is the error returned when the policy does not exist. - ErrNoSuchPolicy = errors.New("no such policy") -) - -// nopMarshaler is an alias to a []byte that implements json.Marshaler -// it bypasses the base64 encoded string representation that json will give byte slices. -// It should only be used to wrap []byte types containing pre-rendered valid json that will later -// (out of the caller's control) be run through json.Marshal -type nopMarshaler []byte - -func (n *nopMarshaler) MarshalJSON() ([]byte, error) { - return *n, nil -} - -// PolicyCreate creates a policy on the server. -func (c *Client) PolicyCreate(ctx context.Context, jsonl []byte) error { - nopm := nopMarshaler(jsonl) - _, err := c.do("POST", PolicyAPIPrefix, doOptions{ - data: &nopm, - context: ctx, - headers: map[string]string{"Content-Type": "application/x-jsonlines"}, - }) - return err -} - -// Policy returns a policy on the server by ID. -func (c *Client) Policy(id string) (*types.Policy, error) { - path := fmt.Sprintf("%s/%s", PolicyAPIPrefix, id) - resp, err := c.do("GET", path, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchPolicy - } - return nil, err - } - defer resp.Body.Close() - - var policy *types.Policy - if err := json.NewDecoder(resp.Body).Decode(&policy); err != nil { - return nil, err - } - return policy, nil -} - -// PolicyList returns the list of policies on the server. -func (c *Client) PolicyList(opts types.ListOptions) (types.PolicySet, error) { - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - namespace: opts.Namespace, - context: opts.Context, - } - - if opts.LabelSelector != "" { - query := url.Values{} - query.Add("labelSelector", opts.LabelSelector) - listOpts.values = query - } - - resp, err := c.do("GET", PolicyAPIPrefix, listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - var policies types.PolicySet - if err := json.NewDecoder(resp.Body).Decode(&policies); err != nil { - return nil, err - } - return policies, nil -} - -// PolicyDelete deletes a policy on the server by ID. -func (c *Client) PolicyDelete(opts types.DeleteOptions) error { - resp, err := c.do("DELETE", PolicyAPIPrefix+"/"+opts.Name, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchPolicy - } - } - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/pool.go b/vendor/github.com/storageos/go-api/pool.go deleted file mode 100644 index b383e77007c..00000000000 --- a/vendor/github.com/storageos/go-api/pool.go +++ /dev/null @@ -1,117 +0,0 @@ -package storageos - -import ( - "encoding/json" - "errors" - "net/http" - - "github.com/storageos/go-api/types" -) - -var ( - - // PoolAPIPrefix is a partial path to the HTTP endpoint. - PoolAPIPrefix = "pools" - - // ErrNoSuchPool is the error returned when the pool does not exist. - ErrNoSuchPool = errors.New("no such pool") - - // ErrPoolInUse is the error returned when the pool requested to be removed is still in use. - ErrPoolInUse = errors.New("pool in use and cannot be removed") -) - -// PoolList returns the list of available pools. -func (c *Client) PoolList(opts types.ListOptions) ([]*types.Pool, error) { - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - namespace: opts.Namespace, - context: opts.Context, - } - resp, err := c.do("GET", PoolAPIPrefix, listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var pools []*types.Pool - if err := json.NewDecoder(resp.Body).Decode(&pools); err != nil { - return nil, err - } - return pools, nil -} - -// PoolCreate creates a pool on the server and returns the new object. -func (c *Client) PoolCreate(opts types.PoolOptions) (*types.Pool, error) { - resp, err := c.do("POST", PoolAPIPrefix, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - var pool types.Pool - if err := json.NewDecoder(resp.Body).Decode(&pool); err != nil { - return nil, err - } - return &pool, nil -} - -// PoolUpdate - update pool -func (c *Client) PoolUpdate(opts types.PoolOptions) (*types.Pool, error) { - ref := opts.Name - if IsUUID(opts.ID) { - ref = opts.ID - } - - resp, err := c.do("PUT", PoolAPIPrefix+"/"+ref, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - var pool types.Pool - if err := json.NewDecoder(resp.Body).Decode(&pool); err != nil { - return nil, err - } - return &pool, nil -} - -// Pool returns a pool by its reference. -func (c *Client) Pool(ref string) (*types.Pool, error) { - resp, err := c.do("GET", PoolAPIPrefix+"/"+ref, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchPool - } - return nil, err - } - defer resp.Body.Close() - var pool types.Pool - if err := json.NewDecoder(resp.Body).Decode(&pool); err != nil { - return nil, err - } - return &pool, nil -} - -// PoolDelete removes a pool by its reference. -func (c *Client) PoolDelete(opts types.DeleteOptions) error { - deleteOpts := doOptions{ - force: opts.Force, - context: opts.Context, - } - resp, err := c.do("DELETE", PoolAPIPrefix+"/"+opts.Name, deleteOpts) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchPool - } - if e.Status == http.StatusConflict { - return ErrPoolInUse - } - } - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/rule.go b/vendor/github.com/storageos/go-api/rule.go deleted file mode 100644 index af1dc196849..00000000000 --- a/vendor/github.com/storageos/go-api/rule.go +++ /dev/null @@ -1,141 +0,0 @@ -package storageos - -import ( - "encoding/json" - "errors" - "net/http" - "net/url" - - "github.com/storageos/go-api/types" -) - -var ( - - // RuleAPIPrefix is a partial path to the HTTP endpoint. - RuleAPIPrefix = "rules" - - // ErrNoSuchRule is the error returned when the rule does not exist. - ErrNoSuchRule = errors.New("no such rule") - - // ErrRuleInUse is the error returned when the rule requested to be removed is still in use. - ErrRuleInUse = errors.New("rule in use and cannot be removed") -) - -// RuleList returns the list of available rules. -func (c *Client) RuleList(opts types.ListOptions) ([]*types.Rule, error) { - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - namespace: opts.Namespace, - context: opts.Context, - } - - if opts.LabelSelector != "" { - query := url.Values{} - query.Add("labelSelector", opts.LabelSelector) - listOpts.values = query - } - - resp, err := c.do("GET", RuleAPIPrefix, listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var rules []*types.Rule - if err := json.NewDecoder(resp.Body).Decode(&rules); err != nil { - return nil, err - } - return rules, nil -} - -// Rule returns a rule by its reference. -func (c *Client) Rule(namespace string, ref string) (*types.Rule, error) { - path, err := namespacedRefPath(namespace, RuleAPIPrefix, ref) - if err != nil { - return nil, err - } - resp, err := c.do("GET", path, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchRule - } - return nil, err - } - defer resp.Body.Close() - var rule types.Rule - if err := json.NewDecoder(resp.Body).Decode(&rule); err != nil { - return nil, err - } - return &rule, nil -} - -// RuleCreate creates a rule on the server and returns the new object. -func (c *Client) RuleCreate(opts types.RuleCreateOptions) (*types.Rule, error) { - path, err := namespacedPath(opts.Namespace, RuleAPIPrefix) - if err != nil { - return nil, err - } - - resp, err := c.do("POST", path, doOptions{ - data: opts, - // namespace: opts.Namespace, - context: opts.Context, - }) - if err != nil { - return nil, err - } - var rule types.Rule - if err := json.NewDecoder(resp.Body).Decode(&rule); err != nil { - return nil, err - } - return &rule, nil -} - -// RuleUpdate updates a rule on the server. -func (c *Client) RuleUpdate(opts types.RuleUpdateOptions) (*types.Rule, error) { - ref := opts.Name - if IsUUID(opts.ID) { - ref = opts.ID - } - - path, err := namespacedRefPath(opts.Namespace, RuleAPIPrefix, ref) - if err != nil { - return nil, err - } - resp, err := c.do("PUT", path, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var rule types.Rule - if err := json.NewDecoder(resp.Body).Decode(&rule); err != nil { - return nil, err - } - return &rule, nil -} - -// RuleDelete removes a rule by its reference. -func (c *Client) RuleDelete(opts types.DeleteOptions) error { - deleteOpts := doOptions{ - namespace: opts.Namespace, - force: opts.Force, - context: opts.Context, - } - resp, err := c.do("DELETE", RuleAPIPrefix+"/"+opts.Name, deleteOpts) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchRule - } - if e.Status == http.StatusConflict { - return ErrRuleInUse - } - } - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/serror/error_kind.go b/vendor/github.com/storageos/go-api/serror/error_kind.go deleted file mode 100644 index 53531398769..00000000000 --- a/vendor/github.com/storageos/go-api/serror/error_kind.go +++ /dev/null @@ -1,11 +0,0 @@ -package serror - -//go:generate stringer -type=StorageOSErrorKind error_kind.go -type StorageOSErrorKind int - -// Known error kinds -const ( - UnknownError StorageOSErrorKind = iota - APIUncontactable - InvalidHostConfig -) diff --git a/vendor/github.com/storageos/go-api/serror/kind_lookup_map.go b/vendor/github.com/storageos/go-api/serror/kind_lookup_map.go deleted file mode 100644 index f96ce6a9d9a..00000000000 --- a/vendor/github.com/storageos/go-api/serror/kind_lookup_map.go +++ /dev/null @@ -1,37 +0,0 @@ -package serror - -import ( - "encoding/json" - "fmt" - "strings" -) - -var kindLookupMap map[string]StorageOSErrorKind - -func init() { - kindLookupMap = make(map[string]StorageOSErrorKind) - - // Populate the lookup map with all the known constants - for i := StorageOSErrorKind(0); !strings.HasPrefix(i.String(), "StorageOSErrorKind("); i++ { - kindLookupMap[i.String()] = i - } -} - -func (s *StorageOSErrorKind) UnmarshalJSON(b []byte) error { - str := "" - if err := json.Unmarshal(b, &str); err != nil { - return err - } - - v, ok := kindLookupMap[str] - if !ok { - return fmt.Errorf("Failed to unmarshal ErrorKind %s", s) - } - - *s = v - return nil -} - -func (s *StorageOSErrorKind) MarshalJSON() ([]byte, error) { - return json.Marshal(s.String()) -} diff --git a/vendor/github.com/storageos/go-api/serror/storageos_error.go b/vendor/github.com/storageos/go-api/serror/storageos_error.go deleted file mode 100644 index 332c19ad677..00000000000 --- a/vendor/github.com/storageos/go-api/serror/storageos_error.go +++ /dev/null @@ -1,34 +0,0 @@ -package serror - -import ( - "encoding/json" -) - -type StorageOSError interface { - // embedding error provides compatibility with standard error handling code - error - - // Encoding/decoding methods to help errors traverse API boundaries - json.Marshaler - json.Unmarshaler - - Err() error // Returns the underlying error that caused this event - String() string // A short string representing the error (for logging etc) - Help() string // A larger string that should provide informative debug instruction to users - Kind() StorageOSErrorKind // A type representing a set of known error conditions, helpful to switch on - Extra() map[string]string // A container for error specific information - - // TODO: should we include callstack traces here? We could have a debug mode for it. -} - -func ErrorKind(err error) StorageOSErrorKind { - if serr, ok := err.(StorageOSError); ok { - return serr.Kind() - } - return UnknownError -} - -func IsStorageOSError(err error) bool { - _, ok := err.(StorageOSError) - return ok -} diff --git a/vendor/github.com/storageos/go-api/serror/storageoserrorkind_string.go b/vendor/github.com/storageos/go-api/serror/storageoserrorkind_string.go deleted file mode 100644 index fafdccc7460..00000000000 --- a/vendor/github.com/storageos/go-api/serror/storageoserrorkind_string.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by "stringer -type=StorageOSErrorKind error_kind.go"; DO NOT EDIT. - -package serror - -import "strconv" - -const _StorageOSErrorKind_name = "UnknownErrorAPIUncontactableInvalidHostConfig" - -var _StorageOSErrorKind_index = [...]uint8{0, 12, 28, 45} - -func (i StorageOSErrorKind) String() string { - if i < 0 || i >= StorageOSErrorKind(len(_StorageOSErrorKind_index)-1) { - return "StorageOSErrorKind(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _StorageOSErrorKind_name[_StorageOSErrorKind_index[i]:_StorageOSErrorKind_index[i+1]] -} diff --git a/vendor/github.com/storageos/go-api/serror/typed_error.go b/vendor/github.com/storageos/go-api/serror/typed_error.go deleted file mode 100644 index 553adec4398..00000000000 --- a/vendor/github.com/storageos/go-api/serror/typed_error.go +++ /dev/null @@ -1,64 +0,0 @@ -package serror - -import ( - "encoding/json" -) - -func NewTypedStorageOSError(kind StorageOSErrorKind, err error, msg string, help string) StorageOSError { - return &typedStorageOSError{ - internal: &internal_TypedStorageOSError{ - ErrorKind: &kind, - Cause: err, - ErrMessage: msg, - HelpMessage: help, - }, - } -} - -func NewUntypedStorageOSError(err error, msg string, help string) StorageOSError { - var kind StorageOSErrorKind = UnknownError - - return &typedStorageOSError{ - internal: &internal_TypedStorageOSError{ - ErrorKind: &kind, - Cause: err, - ErrMessage: msg, - HelpMessage: help, - }, - } -} - -type internal_TypedStorageOSError struct { - ErrorKind *StorageOSErrorKind `json:"error_kind"` - Cause error `json:"caused_by"` - ErrMessage string `json:"error_message"` - HelpMessage string `json:"help_message"` - ExtraMap map[string]string `json:"extra"` -} - -type typedStorageOSError struct { - internal *internal_TypedStorageOSError -} - -func (t *typedStorageOSError) MarshalJSON() ([]byte, error) { - return json.Marshal(t.internal) -} - -func (t *typedStorageOSError) UnmarshalJSON(d []byte) error { - internal := &internal_TypedStorageOSError{} - - err := json.Unmarshal(d, internal) - if err != nil { - return err - } - - t.internal = internal - return nil -} - -func (t *typedStorageOSError) Error() string { return t.String() } -func (t *typedStorageOSError) Err() error { return t.internal.Cause } -func (t *typedStorageOSError) String() string { return t.internal.ErrMessage } -func (t *typedStorageOSError) Help() string { return t.internal.HelpMessage } -func (t *typedStorageOSError) Kind() StorageOSErrorKind { return *t.internal.ErrorKind } -func (t *typedStorageOSError) Extra() map[string]string { return t.internal.ExtraMap } diff --git a/vendor/github.com/storageos/go-api/server_version.go b/vendor/github.com/storageos/go-api/server_version.go deleted file mode 100644 index 3e44aced436..00000000000 --- a/vendor/github.com/storageos/go-api/server_version.go +++ /dev/null @@ -1,28 +0,0 @@ -package storageos - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/storageos/go-api/types" -) - -// ServerVersion returns the server's version and runtime info. -func (c *Client) ServerVersion(ctx context.Context) (*types.VersionInfo, error) { - - // Send as unversioned - resp, err := c.do("GET", "version", doOptions{context: ctx, unversioned: true}) - if err != nil { - return nil, err - } - if resp.StatusCode != http.StatusOK { - return nil, newError(resp) - } - defer resp.Body.Close() - var version types.VersionInfo - if err := json.NewDecoder(resp.Body).Decode(&version); err != nil { - return nil, err - } - return &version, nil -} diff --git a/vendor/github.com/storageos/go-api/template.go b/vendor/github.com/storageos/go-api/template.go deleted file mode 100644 index ca5d4a32292..00000000000 --- a/vendor/github.com/storageos/go-api/template.go +++ /dev/null @@ -1,90 +0,0 @@ -package storageos - -import ( - "encoding/json" - "errors" - "io/ioutil" - "net/http" - "strconv" - - "github.com/storageos/go-api/types" -) - -var ( - - // TemplateAPIPrefix is a partial path to the HTTP endpoint. - TemplateAPIPrefix = "/templates" - - // ErrNoSuchTemplate is the error returned when the template does not exist. - ErrNoSuchTemplate = errors.New("no such template") - - // ErrTemplateInUse is the error returned when the template requested to be removed is still in use. - ErrTemplateInUse = errors.New("template in use and cannot be removed") -) - -// TemplateList returns the list of available templates. -func (c *Client) TemplateList(opts types.ListOptions) ([]types.Template, error) { - path := TemplateAPIPrefix + "?" + queryString(opts) - resp, err := c.do("GET", path, doOptions{context: opts.Context}) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var templates []types.Template - if err := json.NewDecoder(resp.Body).Decode(&templates); err != nil { - return nil, err - } - return templates, nil -} - -// TemplateCreate creates a template on the server and returns the new object. -func (c *Client) TemplateCreate(opts types.TemplateCreateOptions) (string, error) { - resp, err := c.do("POST", TemplateAPIPrefix, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return "", err - } - defer resp.Body.Close() - out, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", err - } - return strconv.Unquote(string(out)) -} - -// Template returns a template by its reference. -func (c *Client) Template(ref string) (*types.Template, error) { - resp, err := c.do("GET", TemplateAPIPrefix+"/"+ref, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchTemplate - } - return nil, err - } - defer resp.Body.Close() - var template types.Template - if err := json.NewDecoder(resp.Body).Decode(&template); err != nil { - return nil, err - } - return &template, nil -} - -// TemplateDelete removes a template by its reference. -func (c *Client) TemplateDelete(ref string) error { - resp, err := c.do("DELETE", TemplateAPIPrefix+"/"+ref, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchTemplate - } - if e.Status == http.StatusConflict { - return ErrTemplateInUse - } - } - return nil - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/types/auth.go b/vendor/github.com/storageos/go-api/types/auth.go deleted file mode 100644 index 16f516b7cb8..00000000000 --- a/vendor/github.com/storageos/go-api/types/auth.go +++ /dev/null @@ -1,14 +0,0 @@ -package types - -// AuthConfig contains authorization information for connecting to a Registry -type AuthConfig struct { - Name string `json:"name,omitempty"` - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Auth string `json:"auth,omitempty"` - ServerAddress string `json:"serveraddress,omitempty"` - - // IdentityToken is used to authenticate the user and get - // an access token for the registry. - IdentityToken string `json:"identitytoken,omitempty"` -} diff --git a/vendor/github.com/storageos/go-api/types/capacity_stats.go b/vendor/github.com/storageos/go-api/types/capacity_stats.go deleted file mode 100644 index 865e253d8a4..00000000000 --- a/vendor/github.com/storageos/go-api/types/capacity_stats.go +++ /dev/null @@ -1,25 +0,0 @@ -package types - -// ErrCapacityStatsUnchanged can be used when comparing stats -const ErrCapacityStatsUnchanged = "no changes" - -// CapacityStats is used to report capacity statistics on pools and controllers. -type CapacityStats struct { - - // TotalCapacityBytes is the object's total capacity in bytes. - TotalCapacityBytes uint64 `json:"totalCapacityBytes"` - - // AvailableCapacityBytes is the object's available capacity in bytes. - AvailableCapacityBytes uint64 `json:"availableCapacityBytes"` - - // ProvisionedCapacityBytes is the object's provisioned capacity in bytes. - ProvisionedCapacityBytes uint64 `json:"provisionedCapacityBytes"` -} - -// IsEqual checks if capacity values are the same -func (c CapacityStats) IsEqual(n CapacityStats) bool { - if c == n { - return true - } - return false -} diff --git a/vendor/github.com/storageos/go-api/types/cluster.go b/vendor/github.com/storageos/go-api/types/cluster.go deleted file mode 100644 index 65625d01210..00000000000 --- a/vendor/github.com/storageos/go-api/types/cluster.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import "time" - -// Maintenance is used to place the cluster in maintenance mode. -type Maintenance struct { - Enabled bool `json:"enabled"` - UpdatedBy string `json:"updatedBy"` - UpdatedAt time.Time `json:"updatedAt"` -} diff --git a/vendor/github.com/storageos/go-api/types/connectivity.go b/vendor/github.com/storageos/go-api/types/connectivity.go deleted file mode 100644 index 8d3177d1ac1..00000000000 --- a/vendor/github.com/storageos/go-api/types/connectivity.go +++ /dev/null @@ -1,41 +0,0 @@ -package types - -import "time" - -// ConnectivityResult capture's a node connectivity report to a given target. -type ConnectivityResult struct { - // Label is a human-readable reference for the service being tested. - Label string `json:"label"` - - // Address is the host:port of the service being tested. - Address string `json:"address"` - - // Source is a human-readable reference for the source host where the tests - // were run from. - Source string `json:"source"` - - // LatencyNS is the duration in nanoseconds that the check took to complete. - // Will also be set on unsuccessful attempts. - LatencyNS time.Duration `json:"latency_ns"` - - // Error is set if the test returned an error. - Error string `json:"error"` -} - -// IsOK returns true iff no error -func (r ConnectivityResult) IsOK() bool { - return len(r.Error) == 0 -} - -// ConnectivityResults is a collection of connectivty reports. -type ConnectivityResults []ConnectivityResult - -// IsOK returns true iff no error in any result. -func (r ConnectivityResults) IsOK() bool { - for _, result := range r { - if !result.IsOK() { - return false - } - } - return true -} diff --git a/vendor/github.com/storageos/go-api/types/delete_options.go b/vendor/github.com/storageos/go-api/types/delete_options.go deleted file mode 100644 index 0355f7d5f5e..00000000000 --- a/vendor/github.com/storageos/go-api/types/delete_options.go +++ /dev/null @@ -1,24 +0,0 @@ -package types - -import "context" - -// DeleteOptions are available parameters for deleting existing volumes. -type DeleteOptions struct { - - // Volume unique ID. - // Read Only: true - ID string `json:"id"` - - // Volume name. - // Read Only: true - Name string `json:"name"` - - // Namespace is the object scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // Force will cause the volume to be deleted even if it's in use. - Force bool `json:"force"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/deployment.go b/vendor/github.com/storageos/go-api/types/deployment.go deleted file mode 100644 index cdc33e4076f..00000000000 --- a/vendor/github.com/storageos/go-api/types/deployment.go +++ /dev/null @@ -1,36 +0,0 @@ -package types - -import "time" - -// Deployment Volume master or replica deployment details. -// swagger:model Deployment -type Deployment struct { - - // Deployment unique ID - // Read Only: true - ID string `json:"id"` - - // Inode number - // Read Only: true - Inode uint32 `json:"inode"` - - // Node ID - // Read Only: true - Node string `json:"node"` - - // Node name - // Read Only: true - NodeName string `json:"nodeName"` - - // Health - // Read Only: true - Health string `json:"health"` - - // Status - // Read Only: true - Status string `json:"status"` - - // Created at - // Read Only: true - CreatedAt time.Time `json:"createdAt"` -} diff --git a/vendor/github.com/storageos/go-api/types/driver_instance.go b/vendor/github.com/storageos/go-api/types/driver_instance.go deleted file mode 100644 index 2ef16b0db32..00000000000 --- a/vendor/github.com/storageos/go-api/types/driver_instance.go +++ /dev/null @@ -1,86 +0,0 @@ -package types - -import "encoding/gob" - -// DriverInstance is used to define an instance of a storage capacity driver. -type DriverInstance struct { - - // Instance unique ID. - // Read Only: true - ID string `json:"id"` - - // Instance name. - Name string `json:"name"` - - // Instance description. - Description string `json:"description"` - - // Flag describing whether the template is active. - // Default: false - Active bool `json:"active"` - - // Config is JSON struct that is passed directly to the driver. There is no - // specific format, and the driver is responsible for validation. - Config interface{} `json:"config"` - - // Labels define a list of labels that describe the driver instance. These - // are inherited from the pool when the driver instance is created. - Labels []string `json:"labels"` - - // ControllerName specifies the controller that this instance is running on. - ControllerName string `json:"controllerName"` - - // PoolID refers to the pool that this driver instance relates to. - PoolID string `json:"poolID"` - - // DriverName specifies which capacity driver this is an instance of. - DriverName string `json:"driverName"` - - // CapacityStats tracks that capacity usage of this driver instance on the - // current controller. - CapacityStats CapacityStats `json:"capacityStats"` -} - -// DriverInstances is a collection of Driver instance objects. -type DriverInstances []*DriverInstance - -func init() { - gob.Register(DriverInstance{}) - gob.Register([]interface{}{}) -} - -// Find an instance matching the parameters. -func (i *DriverInstances) Find(pool string, driver string, controller string) *DriverInstance { - - for _, inst := range *i { - if inst.PoolID == pool && inst.DriverName == driver && inst.ControllerName == controller { - return inst - } - } - return nil -} - -// Add a new instance to the list of instances. -func (i *DriverInstances) Add(new *DriverInstance) { - - for _, inst := range *i { - // Skip if it already exists - if inst.PoolID == new.PoolID && inst.DriverName == new.DriverName && inst.ControllerName == new.ControllerName { - return - } - } - *i = append(*i, new) -} - -// Remove an instance to the list of instances. -func (i *DriverInstances) Remove(id string) { - - // TODO: not working - // for ndx, inst := range *i { - // if inst.ID == id { - // // splice out the item to remove - // *i = append(*i[:ndx], *i[ndx+1:]...) - // return - // } - // } -} diff --git a/vendor/github.com/storageos/go-api/types/error_response.go b/vendor/github.com/storageos/go-api/types/error_response.go deleted file mode 100644 index dc942d9d9ef..00000000000 --- a/vendor/github.com/storageos/go-api/types/error_response.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -// ErrorResponse Represents an error. -// swagger:model ErrorResponse -type ErrorResponse struct { - - // The error message. - // Required: true - Message string `json:"message"` -} diff --git a/vendor/github.com/storageos/go-api/types/events.go b/vendor/github.com/storageos/go-api/types/events.go deleted file mode 100644 index 6e3adf07e6a..00000000000 --- a/vendor/github.com/storageos/go-api/types/events.go +++ /dev/null @@ -1,60 +0,0 @@ -package types - -import "time" - -// EventType describes the type of event -type EventType string - -// EventTypes are added to events to assist with type assertions -const ( - RequestType EventType = "request" - ResponseType = "response" - HeartbeatType = "heartbeat" - BackupType = "backup" -) - -// Event describes the fields that all events should implement. Event is -// intended to be inherherited in more specific Event types. -type Event struct { - ID string `json:"id"` - // Parent is used to specify parent event - Parent string `json:"parent"` - EventType EventType `json:"eventType"` - Action string `json:"action"` - Timestamp int64 `json:"timestamp"` - Status string `json:"status"` - Message string `json:"message"` - Log []string `json:"log"` - ProgressPercent int `json:"progressPercent"` - CreatedBy string `json:"createdBy"` - - Target string `json:"target"` - ActionPayload interface{} `json:"actionPayload"` - - // payload can be encoded into bytes as well - ActionPayloadBytes []byte `json:"actionPayloadBts"` - - UpdatedAt time.Time `json:"updatedAt"` - CreatedAt time.Time `json:"createdAt"` - // retry related value - Retry bool `json:"retry"` - RetriedAt time.Time `json:"retriedAt"` - Attempts int `json:"attempts"` - - // optional parameter - Deadline time.Time `json:"deadline"` - - // optional events to dispatch - Rollback []*Request `json:"rollback"` - RollbackDone bool `json:"rollbackDone"` - - Subject string `json:"subject"` // or "queue" - - // controller ID which created this event - OriginController string `json:"originController"` -} - -// Request is the message structure used for sending request events -type Request struct { - Event -} diff --git a/vendor/github.com/storageos/go-api/types/health.go b/vendor/github.com/storageos/go-api/types/health.go deleted file mode 100644 index 6efe0a4079b..00000000000 --- a/vendor/github.com/storageos/go-api/types/health.go +++ /dev/null @@ -1,148 +0,0 @@ -package types - -import "encoding/json" - -type SubModuleStatus struct { - Status string `json:"status"` - UpdatedAt string `json:"updatedAt"` - ChangedAt string `json:"changedAt"` - Message string `json:"message"` -} - -type NamedSubModuleStatus struct { - Name string - SubModuleStatus -} - -type ClusterHealthNode struct { - NodeID string `json:"nodeID"` - NodeName string `json:"nodeName"` - Submodules struct { - DirectFSInitiator SubModuleStatus `json:"directfs_initiator"` - Director SubModuleStatus `json:"director"` - KV SubModuleStatus `json:"kv"` - KVWrite SubModuleStatus `json:"kv_write"` - NATS SubModuleStatus `json:"nats"` - Presentation SubModuleStatus `json:"presentation"` - RDB SubModuleStatus `json:"rdb"` - } `json:"submodules"` -} - -type CPHealthStatus struct { - KV SubModuleStatus - KVWrite SubModuleStatus - NATS SubModuleStatus - Scheduler SubModuleStatus -} - -func (c *CPHealthStatus) ToNamedSubmodules() []NamedSubModuleStatus { - return []NamedSubModuleStatus{ - {Name: "nats", SubModuleStatus: c.NATS}, - {Name: "kv", SubModuleStatus: c.KV}, - {Name: "kv_write", SubModuleStatus: c.KVWrite}, - {Name: "scheduler", SubModuleStatus: c.Scheduler}, - } -} - -func (c *CPHealthStatus) UnmarshalJSON(data []byte) error { - unmarsh := struct { - Submodules struct { - KV SubModuleStatus `json:"kv"` - KVWrite SubModuleStatus `json:"kv_write"` - NATS SubModuleStatus `json:"nats"` - Scheduler SubModuleStatus `json:"scheduler"` - } `json:"submodules"` - }{} - - if err := json.Unmarshal(data, &unmarsh); err != nil { - return err - } - - c.KV = unmarsh.Submodules.KV - c.KVWrite = unmarsh.Submodules.KVWrite - c.NATS = unmarsh.Submodules.NATS - c.Scheduler = unmarsh.Submodules.Scheduler - - return nil -} - -type DPHealthStatus struct { - DirectFSClient SubModuleStatus - DirectFSServer SubModuleStatus - Director SubModuleStatus - FSDriver SubModuleStatus - FS SubModuleStatus -} - -func (d *DPHealthStatus) ToNamedSubmodules() []NamedSubModuleStatus { - return []NamedSubModuleStatus{ - {Name: "dfs_client", SubModuleStatus: d.DirectFSClient}, - {Name: "dfs_server", SubModuleStatus: d.DirectFSServer}, - {Name: "director", SubModuleStatus: d.Director}, - {Name: "fs_driver", SubModuleStatus: d.FSDriver}, - {Name: "fs", SubModuleStatus: d.FS}, - } -} - -func (d *DPHealthStatus) UnmarshalJSON(data []byte) error { - unmarsh := struct { - Submodules struct { - DirectFSClient SubModuleStatus `json:"directfs-client"` - DirectFSServer SubModuleStatus `json:"directfs-server"` - Director SubModuleStatus `json:"director"` - FSDriver SubModuleStatus `json:"filesystem-driver"` - FS SubModuleStatus `json:"fs"` - } `json:"submodules"` - }{} - - if err := json.Unmarshal(data, &unmarsh); err != nil { - return err - } - - d.DirectFSClient = unmarsh.Submodules.DirectFSClient - d.DirectFSServer = unmarsh.Submodules.DirectFSServer - d.Director = unmarsh.Submodules.Director - d.FSDriver = unmarsh.Submodules.FSDriver - d.FS = unmarsh.Submodules.FS - - return nil -} - -// HealthStatus is the health status json object. -type HealthStatus struct { - Submodules HealthSubmodules `json:"submodules"` -} - -// HealthSubmodules is the "submodules" attribuet of HealthStatus. -type HealthSubmodules struct { - KV SubModuleStatus `json:"kv,omitempty"` - KVWrite SubModuleStatus `json:"kv_write,omitempty"` - NATS SubModuleStatus `json:"nats,omitempty"` - Scheduler SubModuleStatus `json:"scheduler,omitempty"` - DirectFSClient SubModuleStatus `json:"directfs_initiator,omitempty"` - DirectFSServer SubModuleStatus `json:"directfs_responder,omitempty"` - Director SubModuleStatus `json:"director,omitempty"` - FSDriver SubModuleStatus `json:"rdb,omitempty"` - FS SubModuleStatus `json:"presentation,omitempty"` -} - -// ToCPHealthStatus returns only CPHealthStatus from the HealthStatus. -func (h *HealthStatus) ToCPHealthStatus() *CPHealthStatus { - return &CPHealthStatus{ - KV: h.Submodules.KV, - KVWrite: h.Submodules.KVWrite, - NATS: h.Submodules.KVWrite, - Scheduler: h.Submodules.Scheduler, - } -} - -// ToDPHealthStatus returns only DPHealthStatus from the HealthStatus. -func (h *HealthStatus) ToDPHealthStatus() *DPHealthStatus { - return &DPHealthStatus{ - DirectFSClient: h.Submodules.DirectFSClient, - DirectFSServer: h.Submodules.DirectFSServer, - Director: h.Submodules.Director, - FSDriver: h.Submodules.FSDriver, - FS: h.Submodules.FS, - } -} diff --git a/vendor/github.com/storageos/go-api/types/licence.go b/vendor/github.com/storageos/go-api/types/licence.go deleted file mode 100644 index c486ed2bb7b..00000000000 --- a/vendor/github.com/storageos/go-api/types/licence.go +++ /dev/null @@ -1,35 +0,0 @@ -package types - -import "time" - -// FeatureType store features types -type FeatureType string - -const ( - // HA means High Availability - HA = FeatureType("HA") - // DEV means developer licence - DEV = FeatureType("DEV") - // TRIAL means trial licence - TRIAL = FeatureType("TRIAL") -) - -// Licence holds the information to be encoded in the licence key. It needs to be synced across -// the django server running on portal-API as well as the corresponding decoding package on the -// storageOS control plane -type Licence struct { - ArrayUUID string `json:"arrayUUID,omitempty"` - ClusterID string `json:"clusterID,omitempty"` - CustomerID string `json:"customerID"` - CustomerName string `json:"customerName"` - Storage int `json:"storage"` - ValidUntil time.Time `json:"validUntil"` - LicenceType string `json:"licenceType"` - Features map[FeatureType]bool `json:"features"` - Unregistered bool `json:"unregistered"` -} - -// LicenceKeyContainer - stores a licence key -type LicenceKeyContainer struct { - Key string `json:"key"` -} diff --git a/vendor/github.com/storageos/go-api/types/list_options.go b/vendor/github.com/storageos/go-api/types/list_options.go deleted file mode 100644 index caeaead578f..00000000000 --- a/vendor/github.com/storageos/go-api/types/list_options.go +++ /dev/null @@ -1,19 +0,0 @@ -package types - -import "context" - -// ListOptions are optional parameters for finding and listing most objects. -type ListOptions struct { - - // FieldSelector restricts the list of returned objects by their fields. Defaults to everything. - FieldSelector string - - // LabelSelector restricts the list of returned objects by their labels. Defaults to everything. - LabelSelector string - - // Namespace is the object scope, such as for teams and projects. - Namespace string - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context -} diff --git a/vendor/github.com/storageos/go-api/types/logger.go b/vendor/github.com/storageos/go-api/types/logger.go deleted file mode 100644 index f02bad96eb5..00000000000 --- a/vendor/github.com/storageos/go-api/types/logger.go +++ /dev/null @@ -1,40 +0,0 @@ -package types - -import "context" - -// Logger is the runtime configuration of the node's logging services. -// swagger:model Logger -type Logger struct { - - // Node name - Node string `json:"node"` - - // Log level - Level string `json:"level"` - - // Log filter - Filter string `json:"filter"` - - // Log filters by category - // Read Only: true - Categories map[string]string `json:"categories"` -} - -// LoggerUpdateOptions are the available parameters for updating loggers. -type LoggerUpdateOptions struct { - - // Log level - Level string `json:"level"` - - // Log filter - Filter string `json:"filter"` - - // List of nodes to update. All if not set. - Nodes []string `json:"nodes"` - - // List of fields to update. Must be set. - Fields []string `json:"fields"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/namespace.go b/vendor/github.com/storageos/go-api/types/namespace.go deleted file mode 100644 index e82aeeafef6..00000000000 --- a/vendor/github.com/storageos/go-api/types/namespace.go +++ /dev/null @@ -1,59 +0,0 @@ -package types - -import ( - "context" - "time" -) - -// Namespace is used to as a container to isolate namespace and rule obects. -type Namespace struct { - - // Namespace unique ID. - // Read Only: true - ID string `json:"id"` - - // Namespace name. - // Required: true - Name string `json:"name"` - - // The optional DisplayName is how the project is displayed in the web console (defaults to name). - DisplayName string `json:"displayName"` - - // Namespcae description. - Description string `json:"description"` - - // User-defined key/value metadata. - Labels map[string]string `json:"labels"` - - // When the namespace was created. - // Read Only: true - CreatedAt time.Time `json:"createdAt"` - - // User that created the namespace. - // Read Only: true - CreatedBy string `json:"createdBy"` - - // When the namespace was created. - // Read Only: true - UpdatedAt time.Time `json:"updatedAt"` -} - -// NamespaceCreateOptions are available parameters for creating new namespaces. -type NamespaceCreateOptions struct { - - // Name is the name of the namespace to create. - // Required: true - Name string `json:"name"` - - // The optional DisplayName is how the project is displayed in the web console (defaults to name). - DisplayName string `json:"displayName"` - - // Description describes the namespace. - Description string `json:"description"` - - // Labels are user-defined key/value metadata. - Labels map[string]string `json:"labels"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/node.go b/vendor/github.com/storageos/go-api/types/node.go deleted file mode 100644 index 6d60d86110d..00000000000 --- a/vendor/github.com/storageos/go-api/types/node.go +++ /dev/null @@ -1,104 +0,0 @@ -package types - -import ( - "time" -) - -// Node represents a StorageOS cluster node. -type Node struct { - NodeConfig - - HostID uint32 `json:"hostID"` - Name string `json:"name"` - Description string `json:"description"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - - Health string `json:"health"` - HealthUpdatedAt time.Time `json:"healthUpdatedAt"` - - VersionInfo map[string]VersionInfo `json:"versionInfo"` - Version string `json:"version"` - Revision string // the GitCommit this maps to - - Scheduler bool `json:"scheduler"` - - Cordon bool `json:"cordon"` - Drain bool `json:"drain"` - - VolumeStats VolumeStats `json:"volumeStats"` - - // PoolStats map[string]map[string]CapacityStats `json:"poolStats"` - - CapacityStats CapacityStats `json:"capacityStats"` -} - -// NodeConfig is a read-only representation of the node's configuration, set at -// start time by environment variables passed to the container or using defaults. -type NodeConfig struct { - // UUID is the unique identifier of the node. It cannot be changed once set. - ID string `json:"id,omitempty"` - - // Hostname of the node. - Hostname string `json:"hostname"` - - // Address is is used for communication between nodes. - // Nodes will fail to start if the address they first registered with - // changes. This protects against the container being re-scheduled on a - // different host. Nodes will typically use the host server's ip address, - // running the docker container in -net host mode. - Address string `json:"address"` - - // KvAddr is the address of the KV store to use for storing configuration. - // It can include the address or FQDN with optional port. Defaults to - // Address/ADVERTISE_IP. - KvAddr string `json:"kvAddr"` - - // Port allocations - APIPort int `json:"apiPort"` - NatsPort int `json:"natsPort"` - NatsClusterPort int `json:"natsClusterPort"` - SerfPort int `json:"serfPort"` - DFSPort int `json:"dfsPort"` - KVPeerPort int `json:"kvPeerPort"` - KVClientPort int `json:"kvClientPort"` - - Labels map[string]string `json:"labels"` - - LogLevel string `json:"logLevel"` // the level of the logs to outout - LogFormat string `json:"logFormat"` // either text or json - LogFilter string `json:"logFilter"` // used to discard messages based on the message's category - - // BindAddr is used to control the default address StorageOS binds to. This - // should always be set to 0.0.0.0 (all interfaces). - BindAddr string `json:"bindAddr"` - - // DeviceDir is where the volumes are exported. This directory must be - // shared into the container using the rshared volume mount option. - DeviceDir string `json:"deviceDir"` - - // Join existing cluster - Join string `json:"join"` - - // Backend selects the KV backend, either embedded (testing only) or etcd. - Backend string `json:"kvBackend"` - - // EnableDebug is used to enable various debugging features. Used by http - // to enable debug endpoints and as a shortcut to enable debug logging. - EnableDebug bool `json:"debug"` - - // Devices specify all devices that are available on the node. - Devices []Device `json:"devices"` -} - -// Device - device type -type Device struct { - ID string - Labels map[string]string `json:"labels"` - Status string `json:"status"` - Identifier string `json:"identifier"` - Class string `json:"class"` - CapacityStats CapacityStats `json:"capacityStats"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` -} diff --git a/vendor/github.com/storageos/go-api/types/node_update_options.go b/vendor/github.com/storageos/go-api/types/node_update_options.go deleted file mode 100644 index f902567541a..00000000000 --- a/vendor/github.com/storageos/go-api/types/node_update_options.go +++ /dev/null @@ -1,28 +0,0 @@ -package types - -import "context" - -// NodeUpdateOptions are available parameters for updating existing nodes. -type NodeUpdateOptions struct { - - // Node unique ID. - // Read Only: true - ID string `json:"id"` - - // Node name. - // Read Only: true - Name string `json:"name"` - - // Description of the node. - Description string `json:"description"` - - // Labels are user-defined key/value metadata. - Labels map[string]string `json:"labels"` - - // Cordon marks the node as unschedulable if true - Cordon bool `json:"cordon"` - Drain bool `json:"drain"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/operator.go b/vendor/github.com/storageos/go-api/types/operator.go deleted file mode 100644 index 5971a5059e3..00000000000 --- a/vendor/github.com/storageos/go-api/types/operator.go +++ /dev/null @@ -1,19 +0,0 @@ -package types - -// Operator represents a key/field's relationship to value(s). -// See labels.Requirement and fields.Requirement for more details. -type Operator string - -// Valid operators -const ( - None Operator = "" - DoesNotExist Operator = "!" - Equals Operator = "=" - DoubleEquals Operator = "==" - In Operator = "in" - NotEquals Operator = "!=" - NotIn Operator = "notin" - Exists Operator = "exists" - GreaterThan Operator = "gt" - LessThan Operator = "lt" -) diff --git a/vendor/github.com/storageos/go-api/types/policy.go b/vendor/github.com/storageos/go-api/types/policy.go deleted file mode 100644 index 6441939d5e4..00000000000 --- a/vendor/github.com/storageos/go-api/types/policy.go +++ /dev/null @@ -1,45 +0,0 @@ -package types - -import ( - "encoding/json" -) - -type Policy struct { - Spec struct { - User string `json:"user,omitempty"` - Group string `json:"group,omitempty"` - Readonly bool `json:"readonly,omitempty"` - APIGroup string `json:"apiGroup,omitempty"` - Resource string `json:"resource,omitempty"` - Namespace string `json:"namespace,omitempty"` - NonResourcePath string `json:"nonResourcePath,omitempty"` - } `json:"spec"` -} - -// PolicyWithId is used as an internal type to render table formated versions of the json response -type PolicyWithID struct { - Policy - ID string -} - -// MarshalJSON returns a marshaled copy of the internal policy object, so it is still valid to use -// with the REST API -func (p *PolicyWithID) MarshalJSON() ([]byte, error) { - return json.Marshal(p.Policy) -} - -// PolicySet is a representation of the data structure returned from the REST API -type PolicySet map[string]Policy - -func (p PolicySet) GetPoliciesWithID() []*PolicyWithID { - rtn := make([]*PolicyWithID, 0, len(p)) - - for k, v := range p { - rtn = append(rtn, &PolicyWithID{ - Policy: v, - ID: k, - }) - } - - return rtn -} diff --git a/vendor/github.com/storageos/go-api/types/pool.go b/vendor/github.com/storageos/go-api/types/pool.go deleted file mode 100644 index 9487d80551d..00000000000 --- a/vendor/github.com/storageos/go-api/types/pool.go +++ /dev/null @@ -1,39 +0,0 @@ -package types - -// Pool is used to define a capacity pool. -type Pool struct { - - // Pool unique ID. - // Read Only: true - ID string `json:"id"` - - // Pool name. - // Required: true - Name string `json:"name"` - - // Pool description. - Description string `json:"description"` - - // Default determines whether this pool is the default if a volume is - // provisioned without a pool specified. There can only be one default pool. - Default bool `json:"default"` - - NodeSelector string `json:"nodeSelector"` - - // DeviceSelector - specifies a selector to filter node devices based on their labels. - // Only devices from nodes that are in the 'NodeNames' list can be selected - DeviceSelector string `json:"deviceSelector"` - - // Populated by the system. Read-only. - CapacityStats CapacityStats `json:"capacityStats"` - - // This field is computed based on NodeSelector value - // Populated by the system. Read-only. - Nodes []*Node `json:"nodes"` - - // Labels define a list of labels that describe the pool. - Labels map[string]string `json:"labels"` -} - -// Pools is a collection of Pool objects -type Pools []*Pool diff --git a/vendor/github.com/storageos/go-api/types/pool_options.go b/vendor/github.com/storageos/go-api/types/pool_options.go deleted file mode 100644 index dd08a98c0b6..00000000000 --- a/vendor/github.com/storageos/go-api/types/pool_options.go +++ /dev/null @@ -1,28 +0,0 @@ -package types - -import "context" - -// PoolOptions are available parameters for creating or updating pools. -type PoolOptions struct { - ID string `json:"id"` - Name string `json:"name"` - - // Pool description. - Description string `json:"description"` - - // Default determines whether this pool is the default if a volume is - // provisioned without a pool specified. There can only be one default pool. - Default bool `json:"default"` - - NodeSelector string `json:"nodeSelector"` - - // DeviceSelector - specifies a selector to filter node devices based on their labels. - // Only devices from nodes that are in the 'NodeNames' list can be selected - DeviceSelector string `json:"deviceSelector"` - - // Labels define a list of labels that describe the pool. - Labels map[string]string `json:"labels"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/rule.go b/vendor/github.com/storageos/go-api/types/rule.go deleted file mode 100644 index fb7251dfcf3..00000000000 --- a/vendor/github.com/storageos/go-api/types/rule.go +++ /dev/null @@ -1,125 +0,0 @@ -package types - -import "context" - -// Rule is used to define a rule -type Rule struct { - - // Rule unique ID. - // Read Only: true - ID string `json:"id"` - - // Rule name. - // Required: true - Name string `json:"name"` - - // Namespace is the object name and authentication scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // Rule description. - Description string `json:"description"` - - // Flag describing whether the rule is active. - // Default: false - Active bool `json:"active"` - - // Weight is used to determine order during rule processing. Rules with - // heavier weights are processed later. - // default: 0 - Weight int `json:"weight"` - - // RuleAction controls whether the action is to add or remove a label from the - // matching object(s). - RuleAction string `json:"action"` - - // Selectors defines the list of labels that should trigger a rule. - Selector string `json:"selector"` - - // Labels define the list of labels that will be added or removed from the - // matching object(s). - Labels map[string]string `json:"labels"` -} - -// Rules is a collection of Rules. -type Rules []*Rule - -// RuleCreateOptions are available parameters for creating new rules. -type RuleCreateOptions struct { - - // Rule name. - // Required: true - Name string `json:"name"` - - // Namespace is the object name and authentication scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // Rule description. - Description string `json:"description"` - - // Flag describing whether the rule is active. - // Default: false - Active bool `json:"active"` - - // Weight is used to determine order during rule processing. Rules with - // heavier weights are processed later. - // default: 0 - Weight int `json:"weight"` - - // RuleAction controls whether the action is to add or remove a label from the - // matching object(s). - RuleAction string `json:"action"` - - // Selectors defines the list of labels that should trigger a rule. - Selector string `json:"selector"` - - // Labels define the list of labels that will be added or removed from the - // matching object(s). - Labels map[string]string `json:"labels"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} - -// RuleUpdateOptions are available parameters for creating new rules. -type RuleUpdateOptions struct { - - // Rule unique ID. - // Read Only: true - ID string `json:"id"` - - // Rule name. - // Required: true - Name string `json:"name"` - - // Namespace is the object name and authentication scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // Rule description. - Description string `json:"description"` - - // Flag describing whether the rule is active. - // Default: false - Active bool `json:"active"` - - // Weight is used to determine order during rule processing. Rules with - // heavier weights are processed later. - // default: 0 - Weight int `json:"weight"` - - // Operator is used to compare objects or labels. - Operator string `json:"operator"` - - // RuleAction controls whether the action is to add or remove a label from the - // matching object(s). - RuleAction string `json:"action"` - - // Selectors defines the list of labels that should trigger a rule. - Selector string `json:"selector"` - - // Labels define the list of labels that will be added or removed from the - // matching object(s). - Labels map[string]string `json:"labels"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/template.go b/vendor/github.com/storageos/go-api/types/template.go deleted file mode 100644 index 75f8cc7d564..00000000000 --- a/vendor/github.com/storageos/go-api/types/template.go +++ /dev/null @@ -1,53 +0,0 @@ -package types - -// Template is used to define an auto-naming rule. -type Template struct { - - // Template unique ID. - // Read Only: true - ID string `json:"id"` - - // Template name. - // Required: true - Name string `json:"name"` - - // Template description. - Description string `json:"description"` - - // Template format. This is used for pattern matching against labels. - Format string `json:"format"` - - // Autoincrement defines whether there is a dynamic numeric component in the - // template that must auto-increment when objects with the same name already - // exists. - AutoIncrement bool `json:"autoIncrement"` - - // Padding determines whether a dynamic numeric component in the name should - // be padded. - // default: false - Padding bool `json:"padding"` - - // PaddingLength sets the length of the padding. A Padding length of 3 would - // set name similar to `abc001` for the first item. Ignored if Padding set to - // `false`. - PaddingLength int `json:"paddingLength"` - - // Flag describing whether the template is active. - // Default: false - Active bool `json:"active"` - - // Weight is used to determine order during template processing. Templates - // with heavier weights are processed later. - // default: 0 - Weight int `json:"weight"` - - // ObjectTypes defines the type names that the template can be applied to. - ObjectTypes []string `json:"objectTypes"` - - // Labels define a list of the labels that the object must have in order for - // the template to be applied. - Labels map[string]string `json:"labels"` -} - -// Templates is a collection of Template objects -type Templates []*Template diff --git a/vendor/github.com/storageos/go-api/types/template_create_options.go b/vendor/github.com/storageos/go-api/types/template_create_options.go deleted file mode 100644 index 7b905b94389..00000000000 --- a/vendor/github.com/storageos/go-api/types/template_create_options.go +++ /dev/null @@ -1,51 +0,0 @@ -package types - -import "context" - -// TemplateCreateOptions are available parameters for creating new templates. -type TemplateCreateOptions struct { - - // Template name. - // Required: true - Name string `json:"name"` - - // Template description. - Description string `json:"description"` - - // Template format. This is used for pattern matching against labels. - Format string `json:"format"` - - // Autoincrement defines whether there is a dynamic numeric component in the - // template that must auto-increment when objects with the same name already - // exists. - AutoIncrement bool `json:"autoIncrement"` - - // Padding determines whether a dynamic numeric component in the name should - // be padded. - // default: false - Padding bool `json:"padding"` - - // PaddingLength sets the length of the padding. A Padding length of 3 would - // set name similar to `abc001` for the first item. Ignored if Padding set to - // `false`. - PaddingLength int `json:"paddingLength"` - - // Flag describing whether the template is active. - // Default: false - Active bool `json:"active"` - - // Weight is used to determine order during template processing. Templates - // with heavier weights are processed later. - // default: 0 - Weight int `json:"weight"` - - // ObjectTypes defines the type names that the template can be applied to. - ObjectTypes []string `json:"objectTypes"` - - // Labels define a list of the labels that the object must have in order for - // the template to be applied. - Labels map[string]string `json:"labels"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/user.go b/vendor/github.com/storageos/go-api/types/user.go deleted file mode 100644 index aa4bca8ce5b..00000000000 --- a/vendor/github.com/storageos/go-api/types/user.go +++ /dev/null @@ -1,79 +0,0 @@ -package types - -import ( - "context" - "encoding/json" - "strings" -) - -type User struct { - UUID string `json:"id"` - Username string `json:"username"` - Groups []string `json:"groups"` - Password string `json:"password,omitempty"` - Role string `json:"role"` -} - -func (u *User) MarshalJSON() ([]byte, error) { - return json.Marshal(&struct { - UUID string `json:"id"` - Username string `json:"username"` - Groups string `json:"groups"` - Password string `json:"password,omitempty"` - Role string `json:"role"` - }{ - UUID: u.UUID, - Username: u.Username, - Groups: strings.Join(u.Groups, ","), - Password: u.Password, - Role: u.Role, - }) - -} - -func (u *User) UnmarshalJSON(data []byte) error { - temp := &struct { - UUID string `json:"id"` - Username string `json:"username"` - Groups string `json:"groups"` - Password string `json:"password"` - Role string `json:"role"` - }{} - - if err := json.Unmarshal(data, temp); err != nil { - return err - } - - u.UUID = temp.UUID - u.Username = temp.Username - u.Password = temp.Password - u.Role = temp.Role - u.Groups = strings.Split(temp.Groups, ",") - - return nil -} - -type UserCreateOptions struct { - Username string `json:"username"` - Groups []string `json:"groups"` - Password string `json:"password"` - Role string `json:"role"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} - -func (u UserCreateOptions) MarshalJSON() ([]byte, error) { - return json.Marshal(&struct { - Username string `json:"username"` - Groups string `json:"groups"` - Password string `json:"password"` - Role string `json:"role"` - }{ - Username: u.Username, - Groups: strings.Join(u.Groups, ","), - Password: u.Password, - Role: u.Role, - }) - -} diff --git a/vendor/github.com/storageos/go-api/types/version.go b/vendor/github.com/storageos/go-api/types/version.go deleted file mode 100644 index 60da8bf44c9..00000000000 --- a/vendor/github.com/storageos/go-api/types/version.go +++ /dev/null @@ -1,26 +0,0 @@ -package types - -// VersionInfo describes version and runtime info. -type VersionInfo struct { - Name string `json:"name"` - BuildDate string `json:"buildDate"` - Revision string `json:"revision"` - Version string `json:"version"` - APIVersion string `json:"apiVersion"` - GoVersion string `json:"goVersion"` - OS string `json:"os"` - Arch string `json:"arch"` - KernelVersion string `json:"kernelVersion"` - Experimental bool `json:"experimental"` -} - -type VersionResponse struct { - Client *VersionInfo - Server *VersionInfo -} - -// ServerOK returns true when the client could connect to the docker server -// and parse the information received. It returns false otherwise. -func (v VersionResponse) ServerOK() bool { - return v.Server != nil -} diff --git a/vendor/github.com/storageos/go-api/types/volume.go b/vendor/github.com/storageos/go-api/types/volume.go deleted file mode 100644 index 698d7a92d72..00000000000 --- a/vendor/github.com/storageos/go-api/types/volume.go +++ /dev/null @@ -1,143 +0,0 @@ -package types - -import ( - "context" - "time" -) - -// DefaultNamespace is used when a namespace hasn't been specified. -const DefaultNamespace = "default" - -// Volume represents storage volume. -// swagger:model Volume -type Volume struct { - - // Volume unique ID. - // Read Only: true - ID string `json:"id"` - - // Block device inode. - // Read Only: true - Inode uint32 `json:"inode"` - - // Volume name. - // Required: true - Name string `json:"name"` - - // Size in GB. - // Required: true - Size int `json:"size"` - - // Name of capacity pool to provision the volume in, or the name of the current pool. - Pool string `json:"pool"` - - // Filesystem type to mount. May be set on create, or set by rules to influence client. - FSType string `json:"fsType"` - - // Volume description. - Description string `json:"description"` - - // User-defined key/value metadata. - Labels map[string]string `json:"labels"` - - // Namespace is the object name and authentication scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // node selector (where volumes should land) - NodeSelector string `json:"nodeSelector"` - - // Volume deployment information for the master volume. - // Read Only: true - Master *Deployment `json:"master,omitempty"` - - // Flag indicating if the volume is mounted and in use. - // Read Only: true - Mounted bool `json:"mounted"` - - // MountDevice, where the device is located - MountDevice string `json:"mountDevice"` - - // Mountpoint, where the volume is mounted - Mountpoint string `json:"mountpoint"` - - // When the volume was mounted. - // Read Only: true - MountedAt time.Time `json:"mountedAt,omitempty"` - - // Reference to the node that has the volume mounted. - // Read Only: true - MountedBy string `json:"mountedBy,omitempty"` - - // Volume deployment information for the replica volumes. - // Read Only: true - Replicas []*Deployment `json:"replicas"` - - // Volume health, one of: healthy, degraded or dead. - // Read Only: true - Health string `json:"health"` - - // Short status, one of: pending, evaluating, deploying, active, unavailable, failed, updating, deleting. - // Read Only: true - Status string `json:"status"` - - // Status message explaining current status. - // Read Only: true - StatusMessage string `json:"statusMessage"` - - // mkfs performed on new volumes - MkfsDone bool `json:"mkfsDone"` - MkfsDoneAt time.Time `json:"mkfsDoneAt"` - - // When the volume was created. - // Read Only: true - CreatedAt time.Time `json:"createdAt"` - - // User that created the volume. - // Read Only: true - CreatedBy string `json:"createdBy"` -} - -// VolumeMountOptions - used by clients to inform of volume mount operations. -type VolumeMountOptions struct { - - // Volume unique ID. - ID string `json:"id"` - - // Name is the name of the volume to mount. - Name string `json:"name"` - - // Mountpoint, where the volume is mounted - Mountpoint string `json:"mountpoint"` - - // Filesystem type, optional but expected when mounting raw volume - FsType string `json:"fsType"` - - // Namespace is the object scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // The hostname of the client mounting the volume. - Client string `json:"client"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} - -// VolumeUnmountOptions - used by clients to inform of volume mount operations. -type VolumeUnmountOptions struct { - - // Volume unique ID. - ID string `json:"id"` - - // Name is the name of the volume to unmount. - Name string `json:"name"` - - // Namespace is the object scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // The hostname of the client unmounting the volume. Must match the hostname - // of the client that registered the mount operation. - Client string `json:"client"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/volume_create_options.go b/vendor/github.com/storageos/go-api/types/volume_create_options.go deleted file mode 100644 index d7096e1e89a..00000000000 --- a/vendor/github.com/storageos/go-api/types/volume_create_options.go +++ /dev/null @@ -1,36 +0,0 @@ -package types - -import "context" - -// VolumeCreateOptions are available parameters for creating new volumes. -type VolumeCreateOptions struct { - - // Name is the name of the volume to create. - // Required: true - Name string `json:"name"` - - // Description describes the volume. - Description string `json:"description"` - - // Size in GB. - // Required: true - Size int `json:"size"` - - // Pool is the name or id of capacity pool to provision the volume in. - Pool string `json:"pool"` - - // Filesystem type to mount. May be set on create, or set by rules to influence client. - FSType string `json:"fsType"` - - // Namespace is the object scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // node selector (where volumes should land) - NodeSelector string `json:"nodeSelector"` - - // Labels are user-defined key/value metadata. - Labels map[string]string `json:"labels"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/types/volume_stats.go b/vendor/github.com/storageos/go-api/types/volume_stats.go deleted file mode 100644 index cda4de047f1..00000000000 --- a/vendor/github.com/storageos/go-api/types/volume_stats.go +++ /dev/null @@ -1,8 +0,0 @@ -package types - -// VolumeStats - volume stats (volume counts, looking forward to capacity) -type VolumeStats struct { - MasterVolumeCount int `json:"masterVolumeCount"` - ReplicaVolumeCount int `json:"replicaVolumeCount"` - VirtualVolumeCount int `json:"virtualVolumeCount"` -} diff --git a/vendor/github.com/storageos/go-api/types/volume_update_options.go b/vendor/github.com/storageos/go-api/types/volume_update_options.go deleted file mode 100644 index 3c73c6b904e..00000000000 --- a/vendor/github.com/storageos/go-api/types/volume_update_options.go +++ /dev/null @@ -1,34 +0,0 @@ -package types - -import "context" - -// VolumeUpdateOptions are available parameters for updating existing volumes. -type VolumeUpdateOptions struct { - - // Volume unique ID. - // Read Only: true - ID string `json:"id"` - - // Volume name. - // Read Only: true - Name string `json:"name"` - - // Description describes the volume. - Description string `json:"description"` - - // Size in GB. - // Required: true - Size int `json:"size"` - - // Namespace is the object scope, such as for teams and projects. - Namespace string `json:"namespace"` - - // node selector (where volumes should land) - NodeSelector string `json:"nodeSelector"` - - // Labels are user-defined key/value metadata. - Labels map[string]string `json:"labels"` - - // Context can be set with a timeout or can be used to cancel a request. - Context context.Context `json:"-"` -} diff --git a/vendor/github.com/storageos/go-api/user.go b/vendor/github.com/storageos/go-api/user.go deleted file mode 100644 index bfea90105d2..00000000000 --- a/vendor/github.com/storageos/go-api/user.go +++ /dev/null @@ -1,118 +0,0 @@ -package storageos - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "net/url" - - "github.com/storageos/go-api/types" -) - -var ( - // UserAPIPrefix is a partial path to the HTTP endpoint. - UserAPIPrefix = "users" - - // ErrNoSuchUser is the error returned when the user does not exist. - ErrNoSuchUser = errors.New("no such user") -) - -// UserList returns the list of available users. -func (c *Client) UserList(opts types.ListOptions) ([]*types.User, error) { - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - namespace: opts.Namespace, - context: opts.Context, - } - - if opts.LabelSelector != "" { - query := url.Values{} - query.Add("labelSelector", opts.LabelSelector) - listOpts.values = query - } - - resp, err := c.do("GET", UserAPIPrefix, listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - users := make([]*types.User, 0) - if err := json.NewDecoder(resp.Body).Decode(&users); err != nil { - return nil, err - } - return users, nil -} - -// User returns a user by its username/id. -func (c *Client) User(username string) (*types.User, error) { - path := fmt.Sprintf("%s/%s", UserAPIPrefix, username) - resp, err := c.do("GET", path, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchUser - } - return nil, err - } - defer resp.Body.Close() - - var user *types.User - if err := json.NewDecoder(resp.Body).Decode(&user); err != nil { - return nil, err - } - return user, nil -} - -// UserCreate creates a user on the server. -func (c *Client) UserCreate(opts types.UserCreateOptions) error { - _, err := c.do("POST", UserAPIPrefix, doOptions{ - data: opts, - context: opts.Context, - }) - return err -} - -// UserUpdate updates a user on the server. -func (c *Client) UserUpdate(ctx context.Context, user *types.User) error { - var ref string - switch { - case user.UUID != "": - ref = user.UUID - case user.Username != "": - ref = user.Username - default: - return ErrNoSuchUser - } - - path := fmt.Sprintf("%s/%s", UserAPIPrefix, ref) - resp, err := c.do("POST", path, doOptions{ - data: user, - context: ctx, - }) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return ErrNoSuchUser - } - return err - } - defer resp.Body.Close() - return nil -} - -// UserDelete removes a user by its reference. -func (c *Client) UserDelete(opts types.DeleteOptions) error { - resp, err := c.do("DELETE", UserAPIPrefix+"/"+opts.Name, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchUser - } - } - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/github.com/storageos/go-api/util.go b/vendor/github.com/storageos/go-api/util.go deleted file mode 100644 index 21674042d07..00000000000 --- a/vendor/github.com/storageos/go-api/util.go +++ /dev/null @@ -1,16 +0,0 @@ -package storageos - -import ( - "fmt" - "strings" -) - -// ParseRef is a helper to split out the namespace and name from a path -// reference. -func ParseRef(ref string) (namespace string, name string, err error) { - parts := strings.Split(ref, "/") - if len(parts) != 2 { - return "", "", fmt.Errorf("Name must be prefixed with /") - } - return parts[0], parts[1], nil -} diff --git a/vendor/github.com/storageos/go-api/validation.go b/vendor/github.com/storageos/go-api/validation.go deleted file mode 100644 index f58063044ae..00000000000 --- a/vendor/github.com/storageos/go-api/validation.go +++ /dev/null @@ -1,76 +0,0 @@ -package storageos - -import ( - "errors" - "regexp" -) - -const ( - // IDFormat are the characters allowed to represent an ID. - IDFormat = `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}` - - // NameFormat are the characters allowed to represent a name. - NameFormat = `[a-zA-Z0-9][a-zA-Z0-9~_.-]+` -) - -var ( - // IDPattern is a regular expression to validate a unique id against the - // collection of restricted characters. - IDPattern = regexp.MustCompile(`^` + IDFormat + `$`) - - // NamePattern is a regular expression to validate names against the - // collection of restricted characters. - NamePattern = regexp.MustCompile(`^` + NameFormat + `$`) - - // ErrNoRef is given when the reference given is invalid. - ErrNoRef = errors.New("no ref provided or incorrect format") - // ErrNoNamespace is given when the namespace given is invalid. - ErrNoNamespace = errors.New("no namespace provided or incorrect format") -) - -// ValidateNamespaceAndRef returns true if both the namespace and ref are valid. -func ValidateNamespaceAndRef(namespace, ref string) error { - if !IsUUID(ref) && !IsName(ref) { - return ErrNoRef - } - if !IsName(namespace) { - return ErrNoNamespace - } - return nil -} - -// ValidateNamespace returns true if the namespace uses a valid name. -func ValidateNamespace(namespace string) error { - if !IsName(namespace) { - return ErrNoNamespace - } - return nil -} - -// IsUUID returns true if the string input is a valid UUID string. -func IsUUID(s string) bool { - return IDPattern.MatchString(s) -} - -// IsName returns true if the string input is a valid Name string. -func IsName(s string) bool { - return NamePattern.MatchString(s) -} - -// namespacedPath checks for valid input and returns api path for a namespaced -// objectType. Use namespacedRefPath for objects. -func namespacedPath(namespace, objectType string) (string, error) { - if err := ValidateNamespace(namespace); err != nil { - return "", err - } - return "/namespaces/" + namespace + "/" + objectType, nil -} - -// namespacedRefPath checks for valid input and returns api path for a single -// namespaced object. Use namespacedPath for objects type path. -func namespacedRefPath(namespace, objectType, ref string) (string, error) { - if err := ValidateNamespaceAndRef(namespace, ref); err != nil { - return "", err - } - return "/namespaces/" + namespace + "/" + objectType + "/" + ref, nil -} diff --git a/vendor/github.com/storageos/go-api/volume.go b/vendor/github.com/storageos/go-api/volume.go deleted file mode 100644 index d2d7092059e..00000000000 --- a/vendor/github.com/storageos/go-api/volume.go +++ /dev/null @@ -1,197 +0,0 @@ -package storageos - -import ( - "encoding/json" - "errors" - "net/http" - "net/url" - - "github.com/storageos/go-api/types" -) - -var ( - - // VolumeAPIPrefix is a partial path to the HTTP endpoint. - VolumeAPIPrefix = "volumes" - - // ErrNoSuchVolume is the error returned when the volume does not exist. - ErrNoSuchVolume = errors.New("no such volume") - - // ErrVolumeInUse is the error returned when the volume requested to be removed is still in use. - ErrVolumeInUse = errors.New("volume in use and cannot be removed") -) - -// VolumeList returns the list of available volumes. -func (c *Client) VolumeList(opts types.ListOptions) ([]*types.Volume, error) { - listOpts := doOptions{ - fieldSelector: opts.FieldSelector, - labelSelector: opts.LabelSelector, - namespace: opts.Namespace, - context: opts.Context, - } - - if opts.LabelSelector != "" { - query := url.Values{} - query.Add("labelSelector", opts.LabelSelector) - listOpts.values = query - } - - resp, err := c.do("GET", VolumeAPIPrefix, listOpts) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var volumes []*types.Volume - if err := json.NewDecoder(resp.Body).Decode(&volumes); err != nil { - return nil, err - } - return volumes, nil -} - -// Volume returns a volume by its reference. -func (c *Client) Volume(namespace string, ref string) (*types.Volume, error) { - path, err := namespacedRefPath(namespace, VolumeAPIPrefix, ref) - if err != nil { - return nil, err - } - resp, err := c.do("GET", path, doOptions{}) - if err != nil { - if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { - return nil, ErrNoSuchVolume - } - return nil, err - } - defer resp.Body.Close() - var volume types.Volume - if err := json.NewDecoder(resp.Body).Decode(&volume); err != nil { - return nil, err - } - return &volume, nil -} - -// VolumeCreate creates a volume on the server and returns the new object. -func (c *Client) VolumeCreate(opts types.VolumeCreateOptions) (*types.Volume, error) { - path, err := namespacedPath(opts.Namespace, VolumeAPIPrefix) - if err != nil { - return nil, err - } - resp, err := c.do("POST", path, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var volume types.Volume - if err := json.NewDecoder(resp.Body).Decode(&volume); err != nil { - return nil, err - } - return &volume, nil -} - -// VolumeUpdate updates a volume on the server. -func (c *Client) VolumeUpdate(opts types.VolumeUpdateOptions) (*types.Volume, error) { - ref := opts.Name - if IsUUID(opts.ID) { - ref = opts.ID - } - path, err := namespacedRefPath(opts.Namespace, VolumeAPIPrefix, ref) - if err != nil { - return nil, err - } - resp, err := c.do("PUT", path, doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - return nil, err - } - defer resp.Body.Close() - var volume types.Volume - if err := json.NewDecoder(resp.Body).Decode(&volume); err != nil { - return nil, err - } - return &volume, nil -} - -// VolumeDelete removes a volume by its reference. -func (c *Client) VolumeDelete(opts types.DeleteOptions) error { - deleteOpts := doOptions{ - namespace: opts.Namespace, - force: opts.Force, - context: opts.Context, - } - resp, err := c.do("DELETE", VolumeAPIPrefix+"/"+opts.Name, deleteOpts) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchVolume - } - if e.Status == http.StatusConflict { - return ErrVolumeInUse - } - } - return err - } - defer resp.Body.Close() - return nil -} - -// VolumeMount updates the volume with the client that mounted it. -func (c *Client) VolumeMount(opts types.VolumeMountOptions) error { - ref := opts.Name - if IsUUID(opts.ID) { - ref = opts.ID - } - path, err := namespacedRefPath(opts.Namespace, VolumeAPIPrefix, ref) - if err != nil { - return err - } - resp, err := c.do("POST", path+"/mount", doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchVolume - } - if e.Status == http.StatusConflict { - return ErrVolumeInUse - } - } - return err - } - defer resp.Body.Close() - return nil -} - -// VolumeUnmount removes the client from the mount reference. -func (c *Client) VolumeUnmount(opts types.VolumeUnmountOptions) error { - ref := opts.Name - if IsUUID(opts.ID) { - ref = opts.ID - } - path, err := namespacedRefPath(opts.Namespace, VolumeAPIPrefix, ref) - if err != nil { - return err - } - resp, err := c.do("POST", path+"/unmount", doOptions{ - data: opts, - context: opts.Context, - }) - if err != nil { - if e, ok := err.(*Error); ok { - if e.Status == http.StatusNotFound { - return ErrNoSuchVolume - } - if e.Status == http.StatusConflict { - return ErrVolumeInUse - } - } - return err - } - defer resp.Body.Close() - return nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6b8c8b46ea4..a49be7b7619 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -762,12 +762,6 @@ github.com/spf13/pflag # github.com/stoewer/go-strcase v1.2.0 => github.com/stoewer/go-strcase v1.2.0 ## explicit; go 1.11 github.com/stoewer/go-strcase -# github.com/storageos/go-api v2.2.0+incompatible => github.com/storageos/go-api v2.2.0+incompatible -## explicit -github.com/storageos/go-api -github.com/storageos/go-api/netutil -github.com/storageos/go-api/serror -github.com/storageos/go-api/types # github.com/stretchr/objx v0.2.0 => github.com/stretchr/objx v0.2.0 ## explicit; go 1.12 github.com/stretchr/objx @@ -2780,7 +2774,6 @@ sigs.k8s.io/yaml # github.com/spf13/cobra => github.com/spf13/cobra v1.4.0 # github.com/spf13/pflag => github.com/spf13/pflag v1.0.5 # github.com/stoewer/go-strcase => github.com/stoewer/go-strcase v1.2.0 -# github.com/storageos/go-api => github.com/storageos/go-api v2.2.0+incompatible # github.com/stretchr/objx => github.com/stretchr/objx v0.2.0 # github.com/stretchr/testify => github.com/stretchr/testify v1.7.0 # github.com/syndtr/gocapability => github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635