diff --git a/go.mod b/go.mod index b2530bac21..b2676384b6 100644 --- a/go.mod +++ b/go.mod @@ -16,8 +16,6 @@ require ( github.com/Azure/go-autorest/autorest/adal v0.9.23 github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 github.com/Azure/go-autorest/autorest/to v0.4.0 - github.com/BurntSushi/toml v1.3.2 - github.com/IBM/ibmcloud-storage-volume-lib v1.0.2-beta02.0.20190828145158-1da4543a60af github.com/Masterminds/semver v1.5.0 github.com/Masterminds/sprig v2.22.0+incompatible github.com/aws/aws-sdk-go v1.45.7 @@ -34,7 +32,6 @@ require ( github.com/kopia/kopia v0.13.1-0.20230605143225-3551f743d762 github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0 github.com/lib/pq v1.10.9 - github.com/luci/go-render v0.0.0-20160219211803-9a04cc21af0f github.com/mitchellh/mapstructure v1.5.0 //pinned openshift to release-4.5 branch @@ -83,7 +80,6 @@ require ( github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.3.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect @@ -92,7 +88,6 @@ require ( github.com/chai2010/gettext-go v1.0.2 // indirect github.com/chmduquesne/rollinghash v4.0.0+incompatible // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a // indirect @@ -100,7 +95,6 @@ require ( github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect - github.com/fatih/structs v1.1.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -125,10 +119,8 @@ require ( github.com/huandu/xstrings v1.2.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jarcoal/httpmock v1.0.4 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/klauspost/pgzip v1.2.5 // indirect @@ -155,11 +147,9 @@ require ( github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect - github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect github.com/rogpeppe/go-internal v1.6.1 // indirect github.com/rs/xid v1.4.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/softlayer/softlayer-go v0.0.0-20190615201252-ba6e7f295217 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/xlab/treeprint v1.1.0 // indirect github.com/zeebo/blake3 v0.2.3 // indirect diff --git a/go.sum b/go.sum index d80aec059e..68bec19f57 100644 --- a/go.sum +++ b/go.sum @@ -73,14 +73,8 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw= -github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.3.0 h1:gVDpgO5vjgBdr+dSCvHf13WCC2vLsfQM+iyWsn7MjkQ= -github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.3.0/go.mod h1:RiUvKuHKTBmBApDMUQzBL14pQUGKcx/IioKQPIcRQjs= -github.com/IBM/ibmcloud-storage-volume-lib v1.0.2-beta02.0.20190828145158-1da4543a60af h1:1L8wyNvXB1hzvgb8qfJXX/Y9DhFcUGHGhvdw9c30/lY= -github.com/IBM/ibmcloud-storage-volume-lib v1.0.2-beta02.0.20190828145158-1da4543a60af/go.mod h1:xFXCpJFg3Nj3HDgP79Uq/t+DTVFH/9lKxia5e6t49pg= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -125,7 +119,6 @@ github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuA github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= @@ -157,8 +150,6 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/frankban/quicktest v1.13.1 h1:xVm/f9seEhZFL9+n5kv5XLrGwy6elc4V9v/XFY2vmd8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -290,7 +281,6 @@ github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mO github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= @@ -300,8 +290,6 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jarcoal/httpmock v1.0.4 h1:jp+dy/+nonJE4g4xbVtl9QdrUNbn6/3hDT5R4nDIZnA= -github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -321,8 +309,6 @@ github.com/kastenhq/check v0.0.0-20180626002341-0264cfcea734 h1:qulsCaCv+O2y9/sQ github.com/kastenhq/check v0.0.0-20180626002341-0264cfcea734/go.mod h1:rdqSnvOJuKCPFW/h2rVLuXOAkRnHHdp9PZcKx4HCoDM= github.com/kastenhq/stow v0.2.6-kasten.1.0.20230810051814-7e1569eac69b h1:51DAOiKCC7FGxrzFTDaKnj08DCJ4ATffgVg9a2lIP2A= github.com/kastenhq/stow v0.2.6-kasten.1.0.20230810051814-7e1569eac69b/go.mod h1:KCDpsGiySXiaIruvOquULdT8u/7GssXDte2PiqSjDF0= -github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= -github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -356,8 +342,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/luci/go-render v0.0.0-20160219211803-9a04cc21af0f h1:WVPqVsbUsrzAebTEgWRAZMdDOfkFx06iyhbIoyMgtkE= -github.com/luci/go-render v0.0.0-20160219211803-9a04cc21af0f/go.mod h1:aS446i8akEg0DAtNKTVYpNpLPMc0SzsZ0RtGhjl0uFM= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -437,8 +421,6 @@ github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o= -github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= @@ -450,8 +432,6 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/softlayer/softlayer-go v0.0.0-20190615201252-ba6e7f295217 h1:MFHQI+AYM6otrSP+l3dLhE2DjrSr5HXfV4mt4M6pjPs= -github.com/softlayer/softlayer-go v0.0.0-20190615201252-ba6e7f295217/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= @@ -757,13 +737,11 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= diff --git a/pkg/blockstorage/const.go b/pkg/blockstorage/const.go index e3c950f1d0..4fbfb9ad08 100644 --- a/pkg/blockstorage/const.go +++ b/pkg/blockstorage/const.go @@ -30,10 +30,6 @@ const ( TypeGeneric Type = "Generic" // TypeCeph captures enum value "Ceph" TypeCeph Type = "Ceph" - // TypeSoftlayerBlock captures enum value "SoftlayerBlock" - TypeSoftlayerBlock Type = "SoftlayerBlock" - // TypeSoftlayerFile captures enum value "SoftlayerFile" - TypeSoftlayerFile Type = "SoftlayerFile" // TypeEFS captures enum value "EFS" TypeEFS Type = "EFS" // TypeFCD capture enum value for "VMWare FCD" diff --git a/pkg/blockstorage/getter/getter.go b/pkg/blockstorage/getter/getter.go index 7f9f2e259b..9536595cdb 100644 --- a/pkg/blockstorage/getter/getter.go +++ b/pkg/blockstorage/getter/getter.go @@ -16,13 +16,13 @@ package getter import ( "context" + "github.com/pkg/errors" "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/kanisterio/kanister/pkg/blockstorage/awsebs" "github.com/kanisterio/kanister/pkg/blockstorage/azure" "github.com/kanisterio/kanister/pkg/blockstorage/gcepd" - "github.com/kanisterio/kanister/pkg/blockstorage/ibm" ) // Getter is a resolver for a storage provider. @@ -44,13 +44,8 @@ func (*getter) Get(storageType blockstorage.Type, config map[string]string) (blo switch storageType { case blockstorage.TypeEBS: return awsebs.NewProvider(context.TODO(), config) - case blockstorage.TypeSoftlayerBlock: - return ibm.NewProvider(context.TODO(), config) case blockstorage.TypeGPD: return gcepd.NewProvider(config) - case blockstorage.TypeSoftlayerFile: - config[ibm.SoftlayerFileAttName] = "true" - return ibm.NewProvider(context.TODO(), config) case blockstorage.TypeAD: return azure.NewProvider(context.Background(), config) default: @@ -63,12 +58,8 @@ func Supported(st blockstorage.Type) bool { switch st { case blockstorage.TypeEBS: return true - case blockstorage.TypeSoftlayerBlock: - return true case blockstorage.TypeGPD: return true - case blockstorage.TypeSoftlayerFile: - return true case blockstorage.TypeAD: return true default: diff --git a/pkg/blockstorage/ibm/client.go b/pkg/blockstorage/ibm/client.go deleted file mode 100644 index f55573f26b..0000000000 --- a/pkg/blockstorage/ibm/client.go +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2019 The Kanister 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 ibm - -import ( - "context" - "strings" - - "github.com/BurntSushi/toml" - ibmcfg "github.com/IBM/ibmcloud-storage-volume-lib/config" - ibmprov "github.com/IBM/ibmcloud-storage-volume-lib/lib/provider" - ibmprovutils "github.com/IBM/ibmcloud-storage-volume-lib/provider/utils" - "github.com/pkg/errors" - "go.uber.org/zap" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kanisterio/kanister/pkg/kube" - "github.com/kanisterio/kanister/pkg/log" -) - -// IBM Cloud environment variable names -const ( - IBMK8sSecretName = "storage-secret-store" - IBMK8sSecretData = "slclient.toml" - IBMK8sSecretNS = "kube-system" - LibDefCfgEnv = "SECRET_CONFIG_PATH" -) - -var ( - blueMixCfg = ibmcfg.BluemixConfig{ - IamURL: "https://iam.bluemix.net", - IamClientID: "bx", - IamClientSecret: "bx", - IamAPIKey: "free", - RefreshToken: "", - } - - softLayerCfg = ibmcfg.SoftlayerConfig{ - SoftlayerBlockEnabled: true, - SoftlayerBlockProviderName: "SOFTLAYER-BLOCK", - SoftlayerFileEnabled: false, - SoftlayerFileProviderName: "SOFTLAYER-FILE", - SoftlayerUsername: "", - SoftlayerAPIKey: "", - SoftlayerEndpointURL: "https://api.softlayer.com/rest/v3", - SoftlayerIMSEndpointURL: "https://api.softlayer.com/mobile/v3", - SoftlayerDataCenter: "sjc03", - SoftlayerTimeout: "20s", - SoftlayerVolProvisionTimeout: "10m", - SoftlayerRetryInterval: "5s", - } - - vpcCfg = ibmcfg.VPCProviderConfig{ - Enabled: false, - VPCBlockProviderName: "vpc-classic", - } -) - -// client is a wrapper for Library client -type client struct { - Service ibmprov.Session - SLCfg ibmcfg.SoftlayerConfig -} - -// newClient returns a Client struct -func newClient(ctx context.Context, args map[string]string) (*client, error) { - return handleClientPanic(func() (*client, error) { - return newClientUnsafe(ctx, args) - }) -} - -func handleClientPanic(f func() (*client, error)) (c *client, err error) { - defer func() { - r := recover() - if r == nil { - return - } - if e, ok := r.(error); ok { - err = errors.Wrap(e, "IBM client panicked during initialization") - } else { - err = errors.Errorf("IBM client panicked during initialization: %s", r) - } - }() - return f() -} - -// newClientUnsafe may panic. See https://github.com/IBM/ibmcloud-storage-volume-lib/issues/79 -func newClientUnsafe(ctx context.Context, args map[string]string) (*client, error) { - zaplog, _ := zap.NewProduction() - defer zaplog.Sync() //nolint: errcheck - - cfg, err := findDefaultConfig(ctx, args, zaplog) - if err != nil || cfg.Softlayer == nil { - return nil, errors.New("Failed to get IBM client config") - } - - provName := cfg.Softlayer.SoftlayerBlockProviderName - if enableFile, ok := args[SoftlayerFileAttName]; ok && enableFile == "true" { - cfg.Softlayer.SoftlayerFileEnabled = true - cfg.Softlayer.SoftlayerBlockEnabled = false - provName = cfg.Softlayer.SoftlayerFileProviderName - } - - provReg, err := ibmprovutils.InitProviders(cfg, zaplog) - if err != nil { - return nil, errors.Wrap(err, "Failed to Init IBM providers") - } - - session, _, err := ibmprovutils.OpenProviderSession(cfg, provReg, provName, zaplog) - if err != nil { - return nil, errors.Wrapf(err, "Failed to create Open session for IBM provider. %s", provName) - } - - return &client{ - Service: session, - SLCfg: *cfg.Softlayer, - }, nil -} - -func findDefaultConfig(ctx context.Context, args map[string]string, zaplog *zap.Logger) (*ibmcfg.Config, error) { - // Cheking if IBM store secret is present - ibmCfg, err := getDefIBMStoreSecret(ctx, args) - if err == nil { - return ibmCfg, nil - } - log.WithError(err).Print("Could not get IBM default store secret") - // Checking if an api key is provided via args - // If it present will use api value and default Softlayer config - if apik, ok := args[APIKeyArgName]; ok { - blueMixCfg.IamAPIKey = strings.Replace(apik, "\"", "", 2) - return &ibmcfg.Config{ - Softlayer: &softLayerCfg, - Gen2: &ibmcfg.Gen2Config{}, - Bluemix: &blueMixCfg, - VPC: &vpcCfg, - }, nil - } - // Final attemp to get Config, by using default lib code path - defPath := ibmcfg.GetConfPath() - return ibmcfg.ReadConfig(defPath, zaplog) -} - -func getDefIBMStoreSecret(ctx context.Context, args map[string]string) (*ibmcfg.Config, error) { - // Let's check if we are running in k8s and special IBM storage secret is present - k8scli, err := kube.NewClient() - if err != nil { - return nil, errors.Wrap(err, "Failed to created k8s client.") - } - secretNam := IBMK8sSecretName - secretNS := IBMK8sSecretNS - - if sn, ok := args[CfgSecretNameArgName]; ok { - secretNam = sn - } - - if sns, ok := args[CfgSecretNameSpaceArgName]; ok { - secretNS = sns - } - - storeSecret, err := k8scli.CoreV1().Secrets(secretNS).Get(ctx, secretNam, metav1.GetOptions{}) - if err != nil { - return nil, errors.Wrap(err, "Failed to read Default IBM storage secret.") - } - retConfig := ibmcfg.Config{ - Softlayer: &softLayerCfg, - Bluemix: &ibmcfg.BluemixConfig{}, - VPC: &ibmcfg.VPCProviderConfig{}, - } - _, err = toml.Decode(string(storeSecret.Data[IBMK8sSecretData]), &retConfig) - if slapi, ok := args[SLAPIKeyArgName]; ok { - retConfig.Softlayer.SoftlayerAPIKey = slapi - } - if slusername, ok := args[SLAPIUsernameArgName]; ok { - retConfig.Softlayer.SoftlayerUsername = slusername - } - - return &retConfig, err -} diff --git a/pkg/blockstorage/ibm/client_kube_test.go b/pkg/blockstorage/ibm/client_kube_test.go deleted file mode 100644 index d48c02b620..0000000000 --- a/pkg/blockstorage/ibm/client_kube_test.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2019 The Kanister 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. - -//go:build !unit -// +build !unit - -package ibm - -import ( - "context" - "os" - - . "gopkg.in/check.v1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - - "github.com/kanisterio/kanister/pkg/kube" -) - -const ( - testSecretName = "unitetestsecret" - testOldSecretName = "oldibmsecret" - oldTestTomlPath = "./testdata/correct/libconfig_old.toml" -) - -type KubeTestIBMClient struct { - k8sSec *v1.Secret - k8scli kubernetes.Interface -} - -var _ = Suite(&KubeTestIBMClient{}) - -func (s *KubeTestIBMClient) SetUpSuite(c *C) { - var secData []byte - var err error - if tomlPath, ok := os.LookupEnv(workAroundEnv); ok { - secData, err = os.ReadFile(tomlPath) - c.Assert(err, IsNil) - } else { - c.Skip(workAroundEnv + " TOML path is not present") - } - - secretData := make(map[string][]byte) - secretData[IBMK8sSecretData] = secData - - s.k8scli, err = kube.NewClient() - c.Assert(err, IsNil) - k8sSec := v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: testSecretName, - }, - Type: v1.SecretTypeOpaque, - Data: secretData, - } - s.k8sSec, err = s.k8scli.CoreV1().Secrets(IBMK8sSecretNS).Create(context.TODO(), &k8sSec, metav1.CreateOptions{}) - c.Assert(err, IsNil) -} - -func (s KubeTestIBMClient) TearDownSuite(c *C) { - if _, ok := os.LookupEnv(workAroundEnv); !ok { - c.Skip(workAroundEnv + "TOML path is not present") - } - err := s.k8scli.CoreV1().Secrets(s.k8sSec.Namespace).Delete(context.TODO(), s.k8sSec.Name, metav1.DeleteOptions{}) - c.Assert(err, IsNil) -} - -func (s KubeTestIBMClient) TestIBMSecret(c *C) { - apiKey := os.Getenv(IBMApiKeyEnv) - err := os.Unsetenv(IBMApiKeyEnv) - c.Assert(err, IsNil) - defer os.Setenv(IBMApiKeyEnv, apiKey) - ibmCli, err := newClient(context.Background(), map[string]string{CfgSecretNameArgName: testSecretName}) - c.Assert(err, IsNil) - c.Assert(ibmCli, NotNil) - c.Assert(ibmCli.Service, NotNil) - defer ibmCli.Service.Close() - c.Assert(*ibmCli, FitsTypeOf, client{}) - _, err = ibmCli.Service.ListSnapshots() - c.Assert(err, IsNil) -} - -func (s KubeTestIBMClient) TestIBMOldSecret(c *C) { - apiKey := os.Getenv(IBMApiKeyEnv) - err := os.Unsetenv(IBMApiKeyEnv) - c.Assert(err, IsNil) - defer os.Setenv(IBMApiKeyEnv, apiKey) - secData, err := os.ReadFile(oldTestTomlPath) - c.Assert(err, IsNil) - secretData := make(map[string][]byte) - secretData[IBMK8sSecretData] = secData - - s.k8scli, err = kube.NewClient() - c.Assert(err, IsNil) - k8sSec := v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: testOldSecretName, - }, - Type: v1.SecretTypeOpaque, - Data: secretData, - } - s.k8sSec, err = s.k8scli.CoreV1().Secrets(IBMK8sSecretNS).Create(context.TODO(), &k8sSec, metav1.CreateOptions{}) - defer func() { - _ = s.k8scli.CoreV1().Secrets(IBMK8sSecretNS).Delete(context.TODO(), testOldSecretName, metav1.DeleteOptions{}) - }() - c.Assert(err, IsNil) - slAPIKey, ok := os.LookupEnv(IBMSLApiKeyEnv) - c.Check(slAPIKey, NotNil) - c.Check(ok, Equals, true) - slAPIUsername, ok := os.LookupEnv(IBMSLApiUsernameEnv) - c.Check(slAPIUsername, NotNil) - c.Check(ok, Equals, true) - ibmCli, err := newClient(context.Background(), map[string]string{CfgSecretNameArgName: testOldSecretName, SLAPIKeyArgName: slAPIKey, SLAPIUsernameArgName: slAPIUsername}) - c.Assert(err, IsNil) - c.Assert(ibmCli, NotNil) - c.Assert(ibmCli.Service, NotNil) - defer ibmCli.Service.Close() - defer func() { - _ = s.k8scli.CoreV1().Secrets(IBMK8sSecretNS).Delete(context.TODO(), testOldSecretName, metav1.DeleteOptions{}) - }() - c.Assert(*ibmCli, FitsTypeOf, client{}) - _, err = ibmCli.Service.ListSnapshots() - c.Assert(err, IsNil) -} - -func (s *KubeTestIBMClient) TestSecretWSLApiKey(c *C) { - testSlKey := "TestSlKey" - testSlUserName := "TestUserName" - ibmCfg, err := getDefIBMStoreSecret(context.Background(), map[string]string{CfgSecretNameArgName: testSecretName, SLAPIKeyArgName: testSlKey, SLAPIUsernameArgName: testSlUserName}) - c.Assert(err, IsNil) - c.Assert(ibmCfg, NotNil) - c.Assert(ibmCfg.Softlayer.SoftlayerAPIKey, Equals, testSlKey) - c.Assert(ibmCfg.Softlayer.SoftlayerUsername, Equals, testSlUserName) -} diff --git a/pkg/blockstorage/ibm/client_test.go b/pkg/blockstorage/ibm/client_test.go deleted file mode 100644 index f4d52a05fe..0000000000 --- a/pkg/blockstorage/ibm/client_test.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2019 The Kanister 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. - -//go:build !unit -// +build !unit - -package ibm - -import ( - "context" - "fmt" - "os" - "path/filepath" - "testing" - - ibmcfg "github.com/IBM/ibmcloud-storage-volume-lib/config" - - . "gopkg.in/check.v1" -) - -const ( - testBogusPath = "testdata/incorrect" - workAroundEnv = "IBM_STORE_TOML" - IBMApiKeyEnv = "IBM_API_KEY" - IBMSLApiKeyEnv = "IBM_SL_API_KEY" - IBMSLApiUsernameEnv = "IBM_SL_API_USERNAME" -) - -// These are not executed as part of Pipeline, but usefull for development -// Hook up gocheck into the "go test" runner. -func Test(t *testing.T) { TestingT(t) } - -type ClientSuite struct { - apiKey string - slAPIKey string - slAPIUsername string -} - -var _ = Suite(&ClientSuite{}) - -func (s *ClientSuite) SetUpSuite(c *C) { - var ok bool - if s.slAPIKey, ok = os.LookupEnv(IBMSLApiKeyEnv); ok { - if s.slAPIUsername, ok = os.LookupEnv(IBMSLApiUsernameEnv); ok { - return - } - } - if s.apiKey, ok = os.LookupEnv(IBMApiKeyEnv); ok { - return - } - c.Skip(fmt.Sprintf("One of %s, %s and %s environment variable is not set", IBMApiKeyEnv, IBMSLApiKeyEnv, IBMSLApiUsernameEnv)) -} - -func (s *ClientSuite) TearDownSuite(c *C) { - os.Setenv(IBMApiKeyEnv, s.apiKey) - os.Unsetenv(LibDefCfgEnv) -} - -func (s *ClientSuite) TestAPIClient(c *C) { - if tomlPath, ok := os.LookupEnv(workAroundEnv); ok { - err := os.Setenv(LibDefCfgEnv, filepath.Dir(tomlPath)) - c.Assert(err, IsNil) - defer os.Unsetenv(LibDefCfgEnv) - } else { - c.Skip(workAroundEnv + " TOML path is not present") - } - args := s.getCredsMap(c) - ibmCli, err := newClient(context.Background(), args) - c.Assert(err, IsNil) - c.Assert(ibmCli, NotNil) - c.Assert(ibmCli.Service, NotNil) - defer ibmCli.Service.Close() - c.Assert(*ibmCli, FitsTypeOf, client{}) - _, err = ibmCli.Service.ListSnapshots() - c.Assert(err, IsNil) -} - -func (s *ClientSuite) TestIBMClientSoftlayerFile(c *C) { - if tomlPath, ok := os.LookupEnv(workAroundEnv); ok { - err := os.Setenv(LibDefCfgEnv, filepath.Dir(tomlPath)) - c.Assert(err, IsNil) - defer os.Unsetenv(LibDefCfgEnv) - } else { - c.Skip(workAroundEnv + " TOML path is not present") - } - args := s.getCredsMap(c) - args[SoftlayerFileAttName] = "true" - ibmCli, err := newClient(context.Background(), args) - c.Assert(err, IsNil) - defer ibmCli.Service.Close() - c.Assert(ibmCli.Service, NotNil) - c.Assert(*ibmCli, FitsTypeOf, client{}) - c.Assert(ibmCli.SLCfg.SoftlayerBlockEnabled, Equals, false) - c.Assert(ibmCli.SLCfg.SoftlayerFileEnabled, Equals, true) - _, err = ibmCli.Service.ListSnapshots() - c.Assert(err, IsNil) -} - -func (s *ClientSuite) TestDefaultLibConfig(c *C) { - if tomlPath, ok := os.LookupEnv(workAroundEnv); ok { - err := os.Setenv(LibDefCfgEnv, filepath.Dir(tomlPath)) - c.Assert(err, IsNil) - defer os.Unsetenv(LibDefCfgEnv) - } else { - c.Skip(workAroundEnv + " TOML path is not present") - } - apiKey := os.Getenv(IBMApiKeyEnv) - err := os.Unsetenv(IBMApiKeyEnv) - c.Assert(err, IsNil) - defer os.Setenv(IBMApiKeyEnv, apiKey) - ibmCli, err := newClient(context.Background(), make(map[string]string)) - c.Assert(err, IsNil) - c.Assert(ibmCli, NotNil) - c.Assert(ibmCli.Service, NotNil) - defer ibmCli.Service.Close() - c.Assert(*ibmCli, FitsTypeOf, client{}) -} - -func (s *ClientSuite) TestErrorsCases(c *C) { - // Testing for bad secret or not present kubectl - ibmCli, err := newClient(context.Background(), map[string]string{CfgSecretNameArgName: "somename"}) - c.Assert(err, NotNil) - c.Assert(ibmCli, IsNil) - err = os.Setenv(LibDefCfgEnv, "someboguspath") - c.Assert(err, IsNil) - ibmCli, err = newClient(context.Background(), make(map[string]string)) - c.Assert(err, NotNil) - c.Assert(ibmCli, IsNil) - err = os.Setenv(LibDefCfgEnv, testBogusPath) - defer os.Unsetenv(LibDefCfgEnv) - c.Assert(err, IsNil) - ibmCli, err = newClient(context.Background(), make(map[string]string)) - c.Assert(err, NotNil) - c.Assert(ibmCli, IsNil) -} - -func (s *ClientSuite) getCredsMap(c *C) map[string]string { - if s.slAPIKey != "" { - return map[string]string{SLAPIKeyArgName: s.slAPIKey, SLAPIUsernameArgName: s.slAPIUsername} - } - if s.apiKey != "" { - return map[string]string{APIKeyArgName: s.apiKey} - } - c.Skip(fmt.Sprintf("Neither of %s, %s environment variables set", IBMApiKeyEnv, IBMSLApiKeyEnv)) - return map[string]string{} -} - -func (s *ClientSuite) TestPanic(c *C) { - for _, f := range []func() (*client, error){ - func() (*client, error) { - panic("TEST") - }, - func() (*client, error) { - var cfg *client - cfg.SLCfg = ibmcfg.SoftlayerConfig{} - return nil, nil - }, - func() (*client, error) { - var x []int - x[0]++ - return nil, nil - }, - } { - cfg, err := handleClientPanic(f) - c.Assert(err, NotNil) - c.Assert(cfg, IsNil) - } -} diff --git a/pkg/blockstorage/ibm/const.go b/pkg/blockstorage/ibm/const.go deleted file mode 100644 index 873fb0b650..0000000000 --- a/pkg/blockstorage/ibm/const.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2019 The Kanister 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 ibm - -const ( - // APIKeyArgName is used to pass ibmbluemix api key into client. - APIKeyArgName = "api-key" - // SLAPIKeyArgName is used to pass SoftLayer api key into client. - SLAPIKeyArgName = "sl-api-key" - // SLAPIUsernameArgName is used to pass SoftLayer api username into client. - SLAPIUsernameArgName = "sl-api-username" - // CfgSecretNameArgName is used to pass in cluster secret name. - CfgSecretNameArgName = "secret-name" - // CfgSecretNameSpaceArgName is used to pass in cluster secret name. - CfgSecretNameSpaceArgName = "secret-namespace" - // ProviderAttName attribute name for Volume.Provider - ProviderAttName = "Provider" - // ProviderTypeAttName attribute name for Volume.ProviderType - ProviderTypeAttName = "ProviderType" - // SnapshotSpaceAttName attribute name for Volume.SnapshotSpace - SnapshotSpaceAttName = "SnapshotSpace" - // TierAttName attribute name for Volume.Tier - TierAttName = "Tier" - // BillingTypeAttName attribute name for Volume.BillingType - BillingTypeAttName = "BillingType" - // RegionAttName attribute name for Volume.Region - RegionAttName = "Region" - // LunIDAttName attribute name for Volume.LunID - LunIDAttName = "LunID" - // TargetIPsAttName attribute name for Volume.TargetIPAddresses - TargetIPsAttName = "TargetIPAddresses" - // SoftlayerFileAttName attribute name to enable softlayer file support - SoftlayerFileAttName = "SoftlayerFileEnabled" -) diff --git a/pkg/blockstorage/ibm/ibmcloud.go b/pkg/blockstorage/ibm/ibmcloud.go deleted file mode 100644 index f96ae1b2f8..0000000000 --- a/pkg/blockstorage/ibm/ibmcloud.go +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2019 The Kanister 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 ibm - -// IBM Cloud Block storage - -import ( - "context" - "fmt" - "strconv" - "strings" - "time" - - ibmprov "github.com/IBM/ibmcloud-storage-volume-lib/lib/provider" - "github.com/jpillora/backoff" - "github.com/kanisterio/kanister/pkg/poll" - "github.com/pkg/errors" - - "github.com/kanisterio/kanister/pkg/blockstorage" - bsibmutils "github.com/kanisterio/kanister/pkg/blockstorage/ibm/utils" - ktags "github.com/kanisterio/kanister/pkg/blockstorage/tags" - "github.com/kanisterio/kanister/pkg/field" - "github.com/kanisterio/kanister/pkg/log" -) - -var _ blockstorage.Provider = (*ibmCloud)(nil) - -type ibmCloud struct { - cli *client -} - -const ( - defaultTimeout = time.Duration(time.Minute * 5) -) - -func (s *ibmCloud) Type() blockstorage.Type { - if s.cli.SLCfg.SoftlayerFileEnabled { - return blockstorage.TypeSoftlayerFile - } - return blockstorage.TypeSoftlayerBlock -} - -// NewProvider returns a provider for the IBM Cloud -func NewProvider(ctx context.Context, args map[string]string) (blockstorage.Provider, error) { - ibmCli, err := newClient(ctx, args) - return &ibmCloud{cli: ibmCli}, err -} - -func (s *ibmCloud) VolumeCreate(ctx context.Context, volume blockstorage.Volume) (*blockstorage.Volume, error) { - newVol := ibmprov.Volume{} - newVol.VolumeType = ibmprov.VolumeType(volume.VolumeType) - newVol.ProviderType = ibmprov.VolumeProviderType(volume.Attributes[ProviderTypeAttName]) - if volume.Iops > 0 { - iops := strconv.Itoa(int(volume.Iops)) - newVol.Iops = &iops - } - if tier, ok := volume.Attributes[TierAttName]; ok { - newVol.Tier = &tier - } - // size := int(volume.Size) - size := int(blockstorage.SizeInGi(volume.SizeInBytes)) - newVol.Capacity = &size - newVol.VolumeNotes = blockstorage.KeyValueToMap(volume.Tags) - newVol.Az = s.cli.SLCfg.SoftlayerDataCenter - log.Debug().Print("Creating new volume", field.M{"volume": newVol}) - volR, err := s.cli.Service.CreateVolume(newVol) - if err != nil { - return nil, errors.New(fmt.Sprintf("Failed to create volume. %s", err.Error())) - } - log.Debug().Print("New volume created", field.M{"volume": volR}) - return s.volumeParse(ctx, volR) -} - -func (s *ibmCloud) VolumeGet(ctx context.Context, id string, zone string) (*blockstorage.Volume, error) { - vol, err := s.cli.Service.GetVolume(id) - if err != nil { - return nil, errors.Wrapf(err, "Failed to get volume with id %s", id) - } - log.Debug().Print("Got volume from cloud provider", field.M{"Volume": vol}) - return s.volumeParse(ctx, vol) -} - -func (s *ibmCloud) volumeParse(ctx context.Context, vol *ibmprov.Volume) (*blockstorage.Volume, error) { - tags := []*blockstorage.KeyValue(nil) - for k, v := range vol.VolumeNotes { - tags = append(tags, &blockstorage.KeyValue{Key: k, Value: v}) - } - var iops int64 - if vol.Iops != nil { - iops, _ = strconv.ParseInt(*vol.Iops, 10, 64) - } - - attribs := map[string]string{ - ProviderAttName: string(vol.Provider), - ProviderTypeAttName: string(vol.ProviderType), - SnapshotSpaceAttName: "", - TierAttName: "", - BillingTypeAttName: vol.BillingType, - RegionAttName: vol.Region, - } - - if vol.Tier != nil { - attribs[TierAttName] = *vol.Tier - } - - if vol.SnapshotSpace != nil { - attribs[SnapshotSpaceAttName] = strconv.Itoa(*vol.SnapshotSpace) - } - - if vol.LunID == "" && string(vol.Provider) == s.cli.SLCfg.SoftlayerBlockProviderName { - return nil, errors.New("LunID is missing from Volume info") - } - attribs[LunIDAttName] = vol.LunID - - if len(vol.IscsiTargetIPAddresses) == 0 { - return nil, errors.New("IscsiTargetIPAddresses are missing from Volume info") - } - if len(vol.Attributes) > 0 { - for k, v := range vol.Attributes { - attribs[k] = v - } - } - - attribs[TargetIPsAttName] = strings.Join(vol.IscsiTargetIPAddresses, ",") - - return &blockstorage.Volume{ - Type: s.Type(), - ID: vol.VolumeID, - Az: s.cli.SLCfg.SoftlayerDataCenter, // Due to the bug in IBM lib vol.Az, - Encrypted: false, - VolumeType: string(vol.VolumeType), - SizeInBytes: int64(*vol.Capacity) * blockstorage.BytesInGi, - Tags: tags, - Iops: iops, - CreationTime: blockstorage.TimeStamp(vol.CreationTime), - Attributes: attribs, - }, nil -} - -func (s *ibmCloud) VolumesList(ctx context.Context, tags map[string]string, zone string) ([]*blockstorage.Volume, error) { - var vols []*blockstorage.Volume - ibmVols, err := s.cli.Service.ListVolumes(tags) - if err != nil { - return nil, errors.Wrapf(err, "Failed to list volumes with tags %v", tags) - } - - for _, v := range ibmVols { - pvol, err := s.volumeParse(ctx, v) - if err != nil { - return nil, errors.Errorf("Failed to parse vol %s", err.Error()) - } - vols = append(vols, pvol) - } - return vols, nil -} - -func (s *ibmCloud) snapshotParse(ctx context.Context, snap *ibmprov.Snapshot) *blockstorage.Snapshot { - tags := []*blockstorage.KeyValue(nil) - for k, v := range snap.SnapshotTags { - tags = append(tags, &blockstorage.KeyValue{Key: k, Value: v}) - } - - vol := &blockstorage.Volume{ - Type: s.Type(), - ID: snap.VolumeID, - } - - snapSizeInGi := int64(0) - if snap.SnapshotSize != nil { - snapSizeInGi = int64(*snap.SnapshotSize) - } - - return &blockstorage.Snapshot{ - ID: snap.SnapshotID, - Tags: tags, - Type: s.Type(), - Encrypted: false, - SizeInBytes: snapSizeInGi * blockstorage.BytesInGi, - Region: snap.Region, - Volume: vol, - CreationTime: blockstorage.TimeStamp(snap.SnapshotCreationTime), - } -} - -func (s *ibmCloud) SnapshotsList(ctx context.Context, tags map[string]string) ([]*blockstorage.Snapshot, error) { - var snaps []*blockstorage.Snapshot - // IBM doens't support tag for snapshot list. - // Getting all of them - ibmsnaps, err := s.cli.Service.ListSnapshots() - if err != nil { - return nil, errors.Wrap(err, "Failed to list Snapshots") - } - - for _, snap := range ibmsnaps { - snaps = append(snaps, s.snapshotParse(ctx, snap)) - } - return snaps, nil -} - -// SnapshotCopy copies snapshot 'from' to 'to'. Follows aws restrictions regarding encryption; -// i.e., copying unencrypted to encrypted snapshot is allowed but not vice versa. -func (s *ibmCloud) SnapshotCopy(ctx context.Context, from, to blockstorage.Snapshot) (*blockstorage.Snapshot, error) { - return nil, errors.New("Not implemented") -} - -func (s *ibmCloud) SnapshotCopyWithArgs(ctx context.Context, from blockstorage.Snapshot, to blockstorage.Snapshot, args map[string]string) (*blockstorage.Snapshot, error) { - return nil, errors.New("Copy Snapshot with Args not implemented") -} - -func (s *ibmCloud) SnapshotCreate(ctx context.Context, volume blockstorage.Volume, tags map[string]string) (*blockstorage.Snapshot, error) { - alltags := ktags.GetTags(tags) - ibmvol, err := s.cli.Service.GetVolume(volume.ID) - if err != nil { - return nil, errors.Wrapf(err, "Failed to get Volume for Snapshot creation, volume_id :%s", volume.ID) - } - - if ibmvol.SnapshotSpace == nil { - log.Debug().Print("Ordering snapshot space for volume", field.M{"Volume": ibmvol}) - ibmvol.SnapshotSpace = ibmvol.Capacity - err = s.cli.Service.OrderSnapshot(*ibmvol) - if err != nil { - if !strings.Contains(err.Error(), "already has snapshot space") { - return nil, errors.Wrapf(err, "Failed to order Snapshot space, volume_id :%s", volume.ID) - } - } - wctx, wcancel := context.WithTimeout(ctx, defaultTimeout) - defer wcancel() - err = waitforSnapSpaceOrder(wctx, s.cli, volume.ID) - if err != nil { - return nil, errors.Wrapf(err, "Wait is expired for order Snapshot space, volume_id :%s", volume.ID) - } - } - log.Debug().Print("Creating snapshot", field.M{"Volume": ibmvol}) - snap, err := s.cli.Service.CreateSnapshot(ibmvol, alltags) - if err != nil { - return nil, errors.Wrapf(err, "Failed to create snapshot, volume_id: %s", volume.ID) - } - log.Debug().Print("New snapshot was created ", field.M{"Snapshot": snap}) - - return s.snapshotParse(ctx, snap), nil -} - -func (s *ibmCloud) SnapshotCreateWaitForCompletion(ctx context.Context, snap *blockstorage.Snapshot) error { - return nil -} - -func (s *ibmCloud) SnapshotDelete(ctx context.Context, snapshot *blockstorage.Snapshot) error { - snap, err := s.cli.Service.GetSnapshot(snapshot.ID) - if err != nil { - return errors.Wrapf(err, "Failed to get Snapshot for deletion, snapshot_id %s", snapshot.ID) - } - return s.cli.Service.DeleteSnapshot(snap) -} - -func (s *ibmCloud) SnapshotGet(ctx context.Context, id string) (*blockstorage.Snapshot, error) { - snap, err := s.cli.Service.GetSnapshot(id) - if err != nil { - return nil, errors.Wrapf(err, "Failed to get Snapshot, snapshot_id %s", id) - } - return s.snapshotParse(ctx, snap), nil -} - -func (s *ibmCloud) VolumeDelete(ctx context.Context, volume *blockstorage.Volume) error { - ibmvol, err := s.cli.Service.GetVolume(volume.ID) - if err != nil { - return errors.Wrapf(err, "Failed to get Volume for deletion, volume_id :%s", volume.ID) - } - return s.cli.Service.DeleteVolume(ibmvol) -} - -func (s *ibmCloud) SetTags(ctx context.Context, resource interface{}, tags map[string]string) error { - log.Print("IBM storage lib does not support SetTags") - return nil -} - -func (s *ibmCloud) VolumeCreateFromSnapshot(ctx context.Context, snapshot blockstorage.Snapshot, tags map[string]string) (*blockstorage.Volume, error) { - if snapshot.Volume == nil { - return nil, errors.New("Snapshot volume information not available") - } - - // Incorporate pre-existing tags. - for _, tag := range snapshot.Volume.Tags { - if _, found := tags[tag.Key]; !found { - tags[tag.Key] = tag.Value - } - } - snap, err := s.cli.Service.GetSnapshot(snapshot.ID) - if err != nil { - return nil, errors.Wrapf(err, "Failed to get Snapshot for Volume Restore, snapshot_id %s", snapshot.ID) - } - // Temporary fix for Softlayer backend bug - // GetSnapshot doens't return correct Volume info - snap.VolumeID = snapshot.Volume.ID - snap.Volume.VolumeID = snapshot.Volume.ID - log.Debug().Print("Creating Volume from Snapshot with new volume ID", field.M{"inputSnapshot": snap}) - - vol, err := s.cli.Service.CreateVolumeFromSnapshot(*snap, tags) - if err != nil { - return nil, errors.Wrapf(err, "Failed to create Volume from Snapshot, snapshot_id %s", snapshot.ID) - } - - if err = bsibmutils.AuthorizeSoftLayerFileHosts(ctx, vol, s.cli.Service); err != nil { - return nil, errors.Wrap(err, "Failed to add Authorized Hosts to new volume, without Authorized Hosts ibm storage will not be able to mount volume to kubernetes node") - } - - return s.VolumeGet(ctx, vol.VolumeID, snapshot.Volume.Az) -} - -func waitforSnapSpaceOrder(ctx context.Context, cli *client, id string) error { - snapWaitBackoff := backoff.Backoff{ - Factor: 2, - Jitter: false, - Min: 1 * time.Second, - Max: 10 * time.Second, - } - return poll.WaitWithBackoff(ctx, snapWaitBackoff, func(ctx context.Context) (bool, error) { - vol, err := cli.Service.GetVolume(id) - if err != nil { - return false, errors.Wrapf(err, "Failed to get volume, volume_id: %s", id) - } - - if vol.SnapshotSpace != nil { - log.Debug().Print("Volume has snapshot space now", field.M{"volume_id": id}) - return true, nil - } - log.Debug().Print("Still waiting for Snapshor Space order", field.M{"volume_id": id}) - return false, nil - }) -} diff --git a/pkg/blockstorage/ibm/ibmcloud_test.go b/pkg/blockstorage/ibm/ibmcloud_test.go deleted file mode 100644 index 4cf2853dc4..0000000000 --- a/pkg/blockstorage/ibm/ibmcloud_test.go +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2019 The Kanister 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. - -//go:build !unit -// +build !unit - -package ibm - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - "github.com/IBM/ibmcloud-storage-volume-lib/config" - ibmprov "github.com/IBM/ibmcloud-storage-volume-lib/lib/provider" - "github.com/luci/go-render/render" - . "gopkg.in/check.v1" - - "github.com/kanisterio/kanister/pkg/blockstorage" -) - -const ( - testTagKey = "kanister.io/testid" - testTagValue = "unittest" -) - -type TestIBMCloud struct { - provider blockstorage.Provider - cli *client - testVol *blockstorage.Volume - softlayerFile bool - volAtts map[string]string -} - -// These are not executed as part of Pipeline, but usefull for development -var softlayerVolAtts = map[string]string{ - ProviderTypeAttName: string(ibmprov.VolumeProviderType("endurance")), - TierAttName: "2", -} - -var _ = Suite(&TestIBMCloud{softlayerFile: false, volAtts: softlayerVolAtts}) -var _ = Suite(&TestIBMCloud{softlayerFile: true, volAtts: softlayerVolAtts}) - -func (s *TestIBMCloud) SetUpSuite(c *C) { - c.Skip("IBM tests are too flaky to run in CI") - var apiKey string - if apiK, ok := os.LookupEnv(IBMApiKeyEnv); ok { - apiKey = apiK - } else { - c.Skip(fmt.Sprintf("Could not find env var %s with API key", IBMApiKeyEnv)) - } - args := map[string]string{APIKeyArgName: apiKey} - if s.softlayerFile { - args[SoftlayerFileAttName] = "true" - } - - var err error - ctx := context.Background() - s.provider, err = NewProvider(ctx, args) - c.Assert(err, IsNil) - c.Assert(s.provider, NotNil) - s.cli, err = newClient(context.Background(), args) - c.Assert(err, IsNil) - c.Assert(s.cli, NotNil) - tmpVol := &blockstorage.Volume{ - Attributes: s.volAtts, - } - tmpVol.VolumeType = string(s.cli.Service.Type()) - tmpVol.SizeInBytes = 20 * blockstorage.BytesInGi - tmpVol.Tags = []*blockstorage.KeyValue{ - {Key: testTagKey, Value: testTagValue}, - {Key: "kanister.io/testname", Value: c.TestName()}, - } - tmpVol.Az = s.cli.SLCfg.SoftlayerDataCenter - s.testVol, err = s.provider.VolumeCreate(ctx, *tmpVol) - c.Log(fmt.Sprintf("sl cfg %s", render.Render(softLayerCfg))) - c.Assert(err, IsNil) - c.Assert(s.testVol.ID, NotNil) -} - -func (s TestIBMCloud) TearDownSuite(c *C) { - c.Skip("IBM tests are too flaky to run in CI") - // Check whether or not the test volume was initialized - if _, ok := os.LookupEnv(IBMApiKeyEnv); !ok { - c.Skip("Skipping TearDown") - } - c.Assert(s.testVol, NotNil) - bsVol, err := s.provider.VolumeGet(context.Background(), s.testVol.ID, "") - c.Assert(err, IsNil) - err = s.provider.VolumeDelete(context.Background(), bsVol) - c.Assert(err, IsNil) -} - -func (s TestIBMCloud) TestSnapshotCreate(c *C) { - bsVol, err := s.provider.VolumeGet(context.Background(), s.testVol.ID, "") - c.Assert(err, IsNil) - c.Assert(bsVol.ID, Equals, s.testVol.ID) - snapTTags := map[string]string{"ibmblock_unit_test_snap": fmt.Sprintf("test-snap-%d", time.Now().Unix())} - bsSnap, err := s.provider.SnapshotCreate(context.Background(), *bsVol, snapTTags) - c.Assert(err, IsNil) - c.Assert(bsSnap, NotNil) - snaps4Vol, err := s.cli.Service.ListAllSnapshots(bsVol.ID) - c.Assert(err, IsNil) - c.Assert(len(snaps4Vol) > 0, Equals, true) - var inCloud bool - for _, tSnap := range snaps4Vol { - if strings.Compare(tSnap.SnapshotID, bsSnap.ID) == 0 { - inCloud = true - break - } - } - c.Assert(inCloud, Equals, true) - err = s.provider.SnapshotDelete(context.Background(), bsSnap) - c.Check(err, IsNil) -} - -func (s TestIBMCloud) TestVolRestore(c *C) { - bsVol, err := s.provider.VolumeGet(context.Background(), s.testVol.ID, "") - c.Assert(err, IsNil) - snapTTags := map[string]string{"ibmblock_unit_test_snap": fmt.Sprintf("test-snap-%d", time.Now().Unix())} - bsSnap, err := s.provider.SnapshotCreate(context.Background(), *bsVol, snapTTags) - defer s.provider.SnapshotDelete(context.Background(), bsSnap) //nolint: errcheck - c.Assert(err, IsNil) - tTags := map[string]string{"ibmblock_unit_test_restore_vol": fmt.Sprintf("test-vol-%d", time.Now().Unix())} - resVol, err := s.provider.VolumeCreateFromSnapshot(context.Background(), *bsSnap, tTags) - c.Assert(err, IsNil) - cVol, err := s.cli.Service.GetVolume(resVol.ID) - c.Assert(err, IsNil) - c.Assert(cVol, NotNil) - err = s.provider.VolumeDelete(context.Background(), resVol) - c.Assert(err, IsNil) -} - -type TestIBMCloudLocal struct{} - -var _ = Suite(&TestIBMCloudLocal{}) - -func (s TestIBMCloudLocal) TestVolParse(c *C) { - ctx := context.Background() - capInt := 1 - for _, tc := range []struct { - vol *ibmprov.Volume - err Checker - }{ - { - vol: &ibmprov.Volume{ - LunID: "lun", - IscsiTargetIPAddresses: []string{"target"}, - Attributes: map[string]string{ - "key": "value", - }, - Capacity: &capInt, - }, - err: IsNil, - }, - { - vol: &ibmprov.Volume{ - LunID: "lun", - IscsiTargetIPAddresses: []string{}, - Attributes: map[string]string{ - "key": "value", - }, - Capacity: &capInt, - }, - err: NotNil, - }, - { - vol: &ibmprov.Volume{ - LunID: "", - Provider: "slbpname", - IscsiTargetIPAddresses: []string{}, - Attributes: map[string]string{ - "key": "value", - }, - Capacity: &capInt, - }, - err: NotNil, - }, - } { - ic := &ibmCloud{ - cli: &client{ - SLCfg: config.SoftlayerConfig{ - SoftlayerBlockProviderName: "slbpname", - }, - }, - } - _, err := ic.volumeParse(ctx, tc.vol) - c.Assert(err, tc.err) - } -} diff --git a/pkg/blockstorage/ibm/testdata/correct/libconfig.toml b/pkg/blockstorage/ibm/testdata/correct/libconfig.toml deleted file mode 100644 index ed335af683..0000000000 --- a/pkg/blockstorage/ibm/testdata/correct/libconfig.toml +++ /dev/null @@ -1,38 +0,0 @@ -[server] -debug_trace = false - -[bluemix] -iam_url = "https://iam.bluemix.net" -iam_client_id = "bx" -iam_client_secret = "bx" -iam_api_key = "free" -refresh_token = "" -containers_api_route = "https://origin.containers.test.cloud.ibm.com" - -[softlayer] -softlayer_block_enabled = true -softlayer_block_provider_name = "SOFTLAYER-BLOCK" -softlayer_file_enabled = false -softlayer_file_provider_name = "SOFTLAYER-FILE" -softlayer_username = "" -softlayer_api_key = "" -softlayer_endpoint_url = "https://api.softlayer.com/rest/v3" -softlayer_iam_endpoint_url = "https://api.softlayer.com/mobile/v3" -softlayer_datacenter = "sjc03" -softlayer_api_timeout = "30s" -softlayer_vol_provision_timeout = "30m" -softlayer_api_retry_interval = "5s" - -[genesis] -genesis_provider_enabled = false -genesis_user_name = "" -genesis_api_key = "" -genesis_url = "" - -[vpc] -vpc_enabled = false -vpc_block_provider_name = "vpc-classic" - -[iks] -iks_enabled = false -iks_block_provider_name = "iks-vpc-classic" diff --git a/pkg/blockstorage/ibm/testdata/correct/libconfig_old.toml b/pkg/blockstorage/ibm/testdata/correct/libconfig_old.toml deleted file mode 100644 index 3726ba6d16..0000000000 --- a/pkg/blockstorage/ibm/testdata/correct/libconfig_old.toml +++ /dev/null @@ -1,21 +0,0 @@ -[bluemix] -iam_url = "https://iam.bluemix.net" -iam_client_id = "bx" -iam_client_secret = "bx" -iam_api_key = "free" -refresh_token = "" -containers_api_route = "https://origin.containers.test.cloud.ibm.com" - -[softlayer] -softlayer_block_enabled = true -softlayer_block_provider_name = "SOFTLAYER-BLOCK" -softlayer_file_enabled = false -softlayer_file_provider_name = "SOFTLAYER-FILE" -softlayer_username = "" -softlayer_api_key = "" -softlayer_endpoint_url = "https://api.softlayer.com/rest/v3" -softlayer_iam_endpoint_url = "https://api.softlayer.com/mobile/v3" -softlayer_datacenter = "sjc03" -softlayer_api_timeout = "30s" -softlayer_vol_provision_timeout = "30m" -softlayer_api_retry_interval = "5s" diff --git a/pkg/blockstorage/ibm/testdata/incorrect/libconfig.toml b/pkg/blockstorage/ibm/testdata/incorrect/libconfig.toml deleted file mode 100644 index 5f6183769c..0000000000 --- a/pkg/blockstorage/ibm/testdata/incorrect/libconfig.toml +++ /dev/null @@ -1,6 +0,0 @@ -[bluemix] -iam_url = "https://iam.stage1.ng.bluemix.net" -iam_client_id = "bx" -iam_client_secret = "bx" -iam_api_key = "free" -refresh_token = "" diff --git a/pkg/blockstorage/ibm/utils/ibmcloud_utils.go b/pkg/blockstorage/ibm/utils/ibmcloud_utils.go deleted file mode 100644 index 8616947005..0000000000 --- a/pkg/blockstorage/ibm/utils/ibmcloud_utils.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2019 The Kanister 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 ibmutils - -// IBM Cloud utils - -import ( - "context" - - ibmprov "github.com/IBM/ibmcloud-storage-volume-lib/lib/provider" - "github.com/pkg/errors" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kanisterio/kanister/pkg/kube" -) - -// AuthorizeSoftLayerFileHosts some of volumes are required post creation authorization to be mounted -func AuthorizeSoftLayerFileHosts(ctx context.Context, vol *ibmprov.Volume, slCli ibmprov.Session) error { - k8scli, err := kube.NewClient() - if err != nil { - return errors.Wrap(err, "Failed to created k8s client.") - } - - nodes, err := k8scli.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) - if err != nil { - return errors.Wrap(err, "Failed to list nodes") - } - - nodeips := []string{} - - for _, node := range nodes.Items { - for _, ip := range node.Status.Addresses { - if ip.Type == v1.NodeInternalIP { - nodeips = append(nodeips, ip.Address) - } - } - } - - return slCli.AuthorizeVolume(ibmprov.VolumeAuthorization{ - Volume: *vol, - HostIPs: nodeips, - }) -}