diff --git a/CHANGELOG.md b/CHANGELOG.md index addebc8..939c454 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,23 +1,30 @@ -## Version 3.6.0 +## Version 4.0.0 ### Features -- Added validation for required fields in the following resources: - - disks - - lb - - image - - bservice - - vins - - k8s - - k8s_wg - - lb_frontend - - lb_frontend_bind - - lb_backed - - lb_backend_server -- Added status handlers in create/update functions (where present) +- Updated provider to the newest DECORT version (3.8.6): + - resource_k8s now has "network_plugin" required field + - Added "start" argument to resource_k8s + - data_source_bservice, resource_bservice "computes" and "groups" fields now have more in-depth information + - resource_compute now has full boot disk information + - data_source_extnet now has additional field "e_burst" inside "default_qos" substructure + - data_source_rg_list, data_source_rg, resource_rg, resource_account and data_source_account now have two additional fields: + - cpu_allocation_parameter + - cpu_allocation_ratio + - unnecessary fields were removed from all disks data sources && resources (except for unattached disks), to be exact: + - boot_partition + - guid + - disk_path + - iqn + - login + - milestones + - password + - purge_attempts + - reality_device_number + - reference_id +- Removed automatic switch between cloudbroker/cloudapi (admin/user modes) -### Bug Fixes -- Fixed state inconsistency in the following resources/data sources: - - data_source_account - - resource_k8s - - resource_k8s_wg - - resource_account +## Bug Fix +- Fixed resource_compute error when creating a new instance with EXTNET type network +- Fixed quota record marshalling in decort_resgroup resource +- Fixed GID validation for multiple resources +- Fixed possible 'addUser' error when importing resource_account with already added user diff --git a/Makefile b/Makefile index 391049f..743d914 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ ZIPDIR = ./zip BINARY=${NAME}.exe WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH} MAINPATH = ./cmd/decort/ -VERSION=3.6.0 +VERSION=4.0.0 #OS_ARCH=darwin_amd64 OS_ARCH=windows_amd64 #OS_ARCH=linux_amd64 diff --git a/README.md b/README.md index b184e86..735eee8 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Terraform provider для платформы Digital Energy Cloud Orchestration | Версия DECORT API | Версия провайдера Terraform | | ------ | ------ | +| 3.8.6 | 4.x.x | | 3.8.5 | 3.4.x | | 3.8.0 - 3.8.4 | 3.3.1 | | 3.7.x | rc-1.25 | @@ -17,8 +18,8 @@ Terraform provider для платформы Digital Energy Cloud Orchestration Провайдер позволяет работать в двух режимах: - Режим пользователя, -- Режим администратора. - Для переключения между режимами используйте флаг DECORT_ADMIN_MODE. +- Режим администратора.
+ Используйте ресурсы `decort_cb_` для администрирования.
Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki ## Возможности провайдера diff --git a/go.mod b/go.mod index 9bd83ae..effc710 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,8 @@ require ( github.com/hashicorp/terraform-plugin-docs v0.13.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/sirupsen/logrus v1.9.0 - golang.org/x/net v0.4.0 + golang.org/x/net v0.5.0 + repository.basistech.ru/BASIS/decort-golang-sdk v1.4.0 ) require ( @@ -20,8 +21,12 @@ require ( github.com/armon/go-radix v1.0.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/fatih/color v1.13.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.11.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -43,6 +48,7 @@ require ( github.com/hashicorp/yamux v0.1.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.13 // indirect + github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/mitchellh/cli v1.1.5 // indirect @@ -60,11 +66,12 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/zclconf/go-cty v1.12.1 // indirect - golang.org/x/crypto v0.4.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/crypto v0.5.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect google.golang.org/grpc v1.51.0 // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 5d4e732..7171a46 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,10 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI= github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= -github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= @@ -21,14 +14,10 @@ github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C6 github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= -github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= -github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= @@ -39,33 +28,17 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= @@ -75,46 +48,36 @@ github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= +github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= -github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= -github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -126,15 +89,11 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw= -github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ= -github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM= github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -146,44 +105,29 @@ 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/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= -github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= -github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= github.com/hashicorp/hcl/v2 v2.15.0 h1:CPDXO6+uORPjKflkWCCwoWc9uRp+zSIPcCQ+BrxV7m8= github.com/hashicorp/hcl/v2 v2.15.0/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad8zszYZ73Go= -github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8= github.com/hashicorp/terraform-exec v0.17.3 h1:MX14Kvnka/oWGmIkyuyvL6POx25ZmKrjlaclkx3eErU= github.com/hashicorp/terraform-exec v0.17.3/go.mod h1:+NELG0EqQekJzhvikkeQsOAZpsw0cv/03rbeQJqscAI= github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smPzZrt1Wlm9koLeKazY= github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ= -github.com/hashicorp/terraform-plugin-go v0.12.0 h1:6wW9mT1dSs0Xq4LR6HXj1heQ5ovr5GxXNJwkErZzpJw= -github.com/hashicorp/terraform-plugin-go v0.12.0/go.mod h1:kwhmaWHNDvT1B3QiSJdAtrB/D4RaKSY/v3r2BuoWK4M= github.com/hashicorp/terraform-plugin-go v0.14.2 h1:rhsVEOGCnY04msNymSvbUsXfRLKh9znXZmHlf5e8mhE= github.com/hashicorp/terraform-plugin-go v0.14.2/go.mod h1:Q12UjumPNGiFsZffxOsA40Tlz1WVXt2Evh865Zj0+UA= -github.com/hashicorp/terraform-plugin-log v0.6.0 h1:/Vq78uSIdUSZ3iqDc9PESKtwt8YqNKN6u+khD+lLjuw= -github.com/hashicorp/terraform-plugin-log v0.6.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.19.0 h1:7gDAcfto/C4Cjtf90SdukQshsxdMxJ/P69QxiF3digI= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.19.0/go.mod h1:/WYikYjhKB7c2j1HmXZhRsAARldRb4M38bLCLOhC3so= github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 h1:zHcMbxY0+rFO9gY99elV/XC/UnQVg7FhRCbj1i5b7vM= github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1/go.mod h1:+tNlb0wkfdsDJ7JEiERLz4HzM19HyiuIoGzTsM7rPpw= -github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c h1:D8aRO6+mTqHfLsK/BC3j5OAoogv1WLRWzY1AaTo3rBg= -github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI= github.com/hashicorp/terraform-registry-address v0.1.0 h1:W6JkV9wbum+m516rCl5/NjKxCyTVaaUBbzYcMzBDO3U= github.com/hashicorp/terraform-registry-address v0.1.0/go.mod h1:EnyO2jYO6j29DTHbJcm00E5nQTFeTtyZH3H5ycydQ5A= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= @@ -208,21 +152,19 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mitchellh/cli v1.1.4 h1:qj8czE26AU4PbiaPXK5uVmMSM+V5BYsFBiM9HhGRLUA= -github.com/mitchellh/cli v1.1.4/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ= github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -232,8 +174,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -242,9 +182,6 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -254,9 +191,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= @@ -286,7 +221,6 @@ github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaU github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= @@ -295,62 +229,42 @@ github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6e github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -359,10 +273,7 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -371,13 +282,12 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -385,61 +295,26 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc= -google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70= google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -451,12 +326,11 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +repository.basistech.ru/BASIS/decort-golang-sdk v1.4.0 h1:y8F3bzEb8mROEYnoG495AxpbSTEkfSpFh97sZe42cJE= +repository.basistech.ru/BASIS/decort-golang-sdk v1.4.0/go.mod h1:YP57mpXh60xeRERVaCehn+l0S7Qe24trVll1EvrKzds= diff --git a/internal/controller/controller.go b/internal/controller/controller.go index b1b0985..f8a3696 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -35,6 +35,11 @@ import ( // "time" log "github.com/sirupsen/logrus" + decort "repository.basistech.ru/BASIS/decort-golang-sdk" + "repository.basistech.ru/BASIS/decort-golang-sdk/config" + "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker" jwt "github.com/golang-jwt/jwt/v4" @@ -62,6 +67,7 @@ type ControllerCfg struct { oauth2_url string // always required decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification cc_client *http.Client // assigned when all initial checks successfully passed + caller interfaces.Caller } func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) { @@ -147,6 +153,17 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) { return nil, err } ret_config.decort_username = ret_config.legacy_user + + sdkConf := config.LegacyConfig{ + Username: ret_config.legacy_user, + Password: ret_config.legacy_password, + DecortURL: ret_config.controller_url, + Retries: 0, + SSLSkipVerify: allow_unverified_ssl, + } + + ret_config.caller = decort.NewLegacy(sdkConf) + case MODE_JWT: // ok, err := ret_config.validateJWT("") @@ -177,6 +194,17 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) { } else { return nil, fmt.Errorf("Failed to extract user and iss fields from JWT token in oauth2 mode.") } + + sdkConf := config.Config{ + AppID: ret_config.app_id, + AppSecret: ret_config.app_secret, + SSOURL: ret_config.oauth2_url, + DecortURL: ret_config.controller_url, + SSLSkipVerify: allow_unverified_ssl, + } + + ret_config.caller = decort.New(sdkConf) + default: // FYI, this should never happen due to all above checks, but we want to be fool proof return nil, fmt.Errorf("Unknown authenticator mode code %d provided.", ret_config.auth_mode_code) @@ -327,6 +355,26 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) { return true, nil } +func (config *ControllerCfg) CloudAPI() *cloudapi.CloudAPI { + if config.auth_mode_code == MODE_LEGACY { + client, _ := config.caller.(*decort.LegacyDecortClient) + return client.CloudAPI() + } + + client, _ := config.caller.(*decort.DecortClient) + return client.CloudAPI() +} + +func (config *ControllerCfg) CloudBroker() *cloudbroker.CloudBroker { + if config.auth_mode_code == MODE_LEGACY { + client, _ := config.caller.(*decort.LegacyDecortClient) + return client.CloudBroker() + } + + client, _ := config.caller.(*decort.DecortClient) + return client.CloudBroker() +} + func (config *ControllerCfg) DecortAPICall(ctx context.Context, method string, api_name string, url_values *url.Values) (json_resp string, err error) { //nolint:unparam // This is a convenience wrapper around standard HTTP request methods that is aware of the // authorization mode for which the provider was initialized and compiles request accordingly. diff --git a/internal/location/location.go b/internal/location/location.go index eedd3b3..10a772d 100644 --- a/internal/location/location.go +++ b/internal/location/location.go @@ -22,11 +22,10 @@ package location import ( "context" - "encoding/json" "fmt" - "net/url" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -34,17 +33,10 @@ var DefaultGridID int func UtilityLocationGetDefaultGridID(ctx context.Context, m interface{}) (int, error) { c := m.(*controller.ControllerCfg) - - urlValues := &url.Values{} + req := locations.ListRequest{} log.Debug("utilityLocationGetDefaultGridID: retrieving locations list") - apiResp, err := c.DecortAPICall(ctx, "POST", LocationsListAPI, urlValues) - if err != nil { - return 0, err - } - - locList := LocationsListResp{} - err = json.Unmarshal([]byte(apiResp), &locList) + locList, err := c.CloudAPI().Locations().List(ctx, req) if err != nil { return 0, err } @@ -54,7 +46,7 @@ func UtilityLocationGetDefaultGridID(ctx context.Context, m interface{}) (int, e return 0, fmt.Errorf("utilityLocationGetDefaultGridID: retrieved 0 length locations list") } - DefaultGridID = locList[0].GridID + DefaultGridID = int(locList[0].GID) log.Debugf("utilityLocationGetDefaultGridID: default location GridID %d, name %s", DefaultGridID, locList[0].Name) return DefaultGridID, nil diff --git a/internal/provider/cloudbroker/data_sources_map.go b/internal/provider/cloudbroker/data_sources_map.go deleted file mode 100644 index 362a05e..0000000 --- a/internal/provider/cloudbroker/data_sources_map.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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 cloudbroker - -import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu" -) - -func NewDataSourcesMap() map[string]*schema.Resource { - return map[string]*schema.Resource{ - "decort_account": account.DataSourceAccount(), - "decort_account_list": account.DataSourceAccountList(), - "decort_account_computes_list": account.DataSourceAccountComputesList(), - "decort_account_deleted_list": account.DataSourceAccountDeletedList(), - "decort_account_disks_list": account.DataSourceAccountDisksList(), - "decort_account_flipgroups_list": account.DataSourceAccountFlipGroupsList(), - "decort_account_rg_list": account.DataSourceAccountRGList(), - "decort_account_vins_list": account.DataSourceAccountVinsList(), - "decort_account_audits_list": account.DataSourceAccountAuditsList(), - "decort_disk": disks.DataSourceDisk(), - "decort_disk_list": disks.DataSourceDiskList(), - "decort_image": image.DataSourceImage(), - "decort_grid": grid.DataSourceGrid(), - "decort_grid_list": grid.DataSourceGridList(), - "decort_image_list": image.DataSourceImageList(), - "decort_image_list_stacks": image.DataSourceImageListStacks(), - "decort_pcidevice": pcidevice.DataSourcePcidevice(), - "decort_pcidevice_list": pcidevice.DataSourcePcideviceList(), - "decort_sep_list": sep.DataSourceSepList(), - "decort_sep": sep.DataSourceSep(), - "decort_sep_consumption": sep.DataSourceSepConsumption(), - "decort_sep_disk_list": sep.DataSourceSepDiskList(), - "decort_sep_config": sep.DataSourceSepConfig(), - "decort_sep_pool": sep.DataSourceSepPool(), - "decort_vgpu": vgpu.DataSourceVGPU(), - "decort_rg_list": rg.DataSourceRgList(), - // "decort_pfw": dataSourcePfw(), - } - -} diff --git a/internal/provider/cloudbroker/resources_map.go b/internal/provider/cloudbroker/resources_map.go deleted file mode 100644 index 04229c0..0000000 --- a/internal/provider/cloudbroker/resources_map.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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 cloudbroker - -import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pfw" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/snapshot" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins" -) - -func NewRersourcesMap() map[string]*schema.Resource { - return map[string]*schema.Resource{ - "decort_account": account.ResourceAccount(), - "decort_disk": disks.ResourceDisk(), - "decort_image": image.ResourceImage(), - "decort_virtual_image": image.ResourceVirtualImage(), - "decort_cdrom_image": image.ResourceCDROMImage(), - "decort_delete_images": image.ResourceDeleteImages(), - "decort_pcidevice": pcidevice.ResourcePcidevice(), - "decort_sep": sep.ResourceSep(), - "decort_sep_config": sep.ResourceSepConfig(), - "decort_resgroup": rg.ResourceResgroup(), - "decort_kvmvm": kvmvm.ResourceCompute(), - "decort_vins": vins.ResourceVins(), - "decort_pfw": pfw.ResourcePfw(), - "decort_k8s": k8s.ResourceK8s(), - "decort_k8s_wg": k8s.ResourceK8sWg(), - "decort_snapshot": snapshot.ResourceSnapshot(), - } -} diff --git a/internal/provider/cloudapi/data_sources_map.go b/internal/provider/data_sources_map.go similarity index 71% rename from internal/provider/cloudapi/data_sources_map.go rename to internal/provider/data_sources_map.go index 206ab57..424e249 100644 --- a/internal/provider/cloudapi/data_sources_map.go +++ b/internal/provider/data_sources_map.go @@ -18,7 +18,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cloudapi +package provider import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -34,9 +34,18 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins" + + cb_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account" + cb_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks" + cb_grid "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/grid" + cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" + cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" + cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" + cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" + cb_vgpu "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vgpu" ) -func NewDataSourcesMap() map[string]*schema.Resource { +func newDataSourcesMap() map[string]*schema.Resource { return map[string]*schema.Resource{ "decort_account": account.DataSourceAccount(), "decort_resgroup": rg.DataSourceResgroup(), @@ -109,7 +118,33 @@ func NewDataSourcesMap() map[string]*schema.Resource { "decort_lb": lb.DataSourceLB(), "decort_lb_list": lb.DataSourceLBList(), "decort_lb_list_deleted": lb.DataSourceLBListDeleted(), - // "decort_pfw": dataSourcePfw(), + + "decort_cb_account": cb_account.DataSourceAccount(), + "decort_cb_account_list": cb_account.DataSourceAccountList(), + "decort_cb_account_computes_list": cb_account.DataSourceAccountComputesList(), + "decort_cb_account_deleted_list": cb_account.DataSourceAccountDeletedList(), + "decort_cb_account_disks_list": cb_account.DataSourceAccountDisksList(), + "decort_cb_account_flipgroups_list": cb_account.DataSourceAccountFlipGroupsList(), + "decort_cb_account_rg_list": cb_account.DataSourceAccountRGList(), + "decort_cb_account_vins_list": cb_account.DataSourceAccountVinsList(), + "decort_cb_account_audits_list": cb_account.DataSourceAccountAuditsList(), + "decort_cb_disk": cb_disks.DataSourceDisk(), + "decort_cb_disk_list": cb_disks.DataSourceDiskList(), + "decort_cb_image": cb_image.DataSourceImage(), + "decort_cb_grid": cb_grid.DataSourceGrid(), + "decort_cb_grid_list": cb_grid.DataSourceGridList(), + "decort_cb_image_list": cb_image.DataSourceImageList(), + "decort_cb_image_list_stacks": cb_image.DataSourceImageListStacks(), + "decort_cb_pcidevice": cb_pcidevice.DataSourcePcidevice(), + "decort_cb_pcidevice_list": cb_pcidevice.DataSourcePcideviceList(), + "decort_cb_sep_list": cb_sep.DataSourceSepList(), + "decort_cb_sep": cb_sep.DataSourceSep(), + "decort_cb_sep_consumption": cb_sep.DataSourceSepConsumption(), + "decort_cb_sep_disk_list": cb_sep.DataSourceSepDiskList(), + "decort_cb_sep_config": cb_sep.DataSourceSepConfig(), + "decort_cb_sep_pool": cb_sep.DataSourceSepPool(), + "decort_cb_vgpu": cb_vgpu.DataSourceVGPU(), + "decort_cb_rg_list": cb_rg.DataSourceRgList(), } } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index ac58577..6134e45 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -103,9 +103,9 @@ func Provider() *schema.Provider { }, }, - ResourcesMap: selectSchema(false), + ResourcesMap: newResourcesMap(), - DataSourcesMap: selectSchema(true), + DataSourcesMap: newDataSourcesMap(), ConfigureContextFunc: providerConfigure, } diff --git a/internal/provider/cloudapi/resource_map.go b/internal/provider/resource_map.go similarity index 57% rename from internal/provider/cloudapi/resource_map.go rename to internal/provider/resource_map.go index bc65c4b..db6ab32 100644 --- a/internal/provider/cloudapi/resource_map.go +++ b/internal/provider/resource_map.go @@ -18,7 +18,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cloudapi +package provider import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -33,9 +33,21 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins" + + cb_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account" + cb_disks "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/disks" + cb_image "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/image" + cb_k8s "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/k8s" + cb_kvmvm "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/kvmvm" + cb_pcidevice "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pcidevice" + cb_pfw "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/pfw" + cb_rg "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/rg" + cb_sep "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/sep" + cb_snapshot "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/snapshot" + cb_vins "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/vins" ) -func NewRersourcesMap() map[string]*schema.Resource { +func newResourcesMap() map[string]*schema.Resource { return map[string]*schema.Resource{ "decort_resgroup": rg.ResourceResgroup(), "decort_kvmvm": kvmvm.ResourceCompute(), @@ -56,5 +68,22 @@ func NewRersourcesMap() map[string]*schema.Resource { "decort_lb_backend_server": lb.ResourceLBBackendServer(), "decort_lb_frontend": lb.ResourceLBFrontend(), "decort_lb_frontend_bind": lb.ResourceLBFrontendBind(), + + "decort_cb_account": cb_account.ResourceAccount(), + "decort_cb_disk": cb_disks.ResourceDisk(), + "decort_cb_image": cb_image.ResourceImage(), + "decort_cb_virtual_image":cb_image.ResourceVirtualImage(), + "decort_cb_cdrom_image": cb_image.ResourceCDROMImage(), + "decort_cb_delete_images":cb_image.ResourceDeleteImages(), + "decort_cb_pcidevice": cb_pcidevice.ResourcePcidevice(), + "decort_cb_sep": cb_sep.ResourceSep(), + "decort_cb_sep_config": cb_sep.ResourceSepConfig(), + "decort_cb_resgroup": cb_rg.ResourceResgroup(), + "decort_cb_kvmvm": cb_kvmvm.ResourceCompute(), + "decort_cb_vins": cb_vins.ResourceVins(), + "decort_cb_pfw": cb_pfw.ResourcePfw(), + "decort_cb_k8s": cb_k8s.ResourceK8s(), + "decort_cb_k8s_wg": cb_k8s.ResourceK8sWg(), + "decort_cb_snapshot": cb_snapshot.ResourceSnapshot(), } } diff --git a/internal/provider/select_schema.go b/internal/provider/select_schema.go deleted file mode 100644 index 4538110..0000000 --- a/internal/provider/select_schema.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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 provider - -import ( - "os" - "strconv" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - ca "repository.basistech.ru/BASIS/terraform-provider-decort/internal/provider/cloudapi" - cb "repository.basistech.ru/BASIS/terraform-provider-decort/internal/provider/cloudbroker" -) - -func selectSchema(isDatasource bool) map[string]*schema.Resource { - adminMode, err := strconv.ParseBool(os.Getenv("DECORT_ADMIN_MODE")) - if err != nil { - adminMode = false - } - if isDatasource { - return selectDataSourceSchema(adminMode) - } - return selectResourceSchema(adminMode) - -} - -func selectDataSourceSchema(adminMode bool) map[string]*schema.Resource { - if adminMode { - return cb.NewDataSourcesMap() - } - return ca.NewDataSourcesMap() -} - -func selectResourceSchema(adminMode bool) map[string]*schema.Resource { - if adminMode { - return cb.NewRersourcesMap() - } - return ca.NewRersourcesMap() -} diff --git a/internal/service/cloudapi/account/api.go b/internal/service/cloudapi/account/api.go deleted file mode 100644 index 1d89972..0000000 --- a/internal/service/cloudapi/account/api.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package account - -const accountAddUserAPI = "/restmachine/cloudapi/account/addUser" -const accountAuditsAPI = "/restmachine/cloudapi/account/audits" -const accountCreateAPI = "/restmachine/cloudapi/account/create" -const accountDeleteAPI = "/restmachine/cloudapi/account/delete" -const accountDeleteUserAPI = "/restmachine/cloudapi/account/deleteUser" -const accountDisableAPI = "/restmachine/cloudapi/account/disable" -const accountEnableAPI = "/restmachine/cloudapi/account/enable" -const accountGetAPI = "/restmachine/cloudapi/account/get" -const accountGetConsumedUnitsAPI = "/restmachine/cloudapi/account/getConsumedAccountUnits" -const accountGetConsumedUnitsByTypeAPI = "/restmachine/cloudapi/account/getConsumedCloudUnitsByType" -const accountGetReservedUnitsAPI = "/restmachine/cloudapi/account/getReservedAccountUnits" -const accountListAPI = "/restmachine/cloudapi/account/list" -const accountListComputesAPI = "/restmachine/cloudapi/account/listComputes" -const accountListDeletedAPI = "/restmachine/cloudapi/account/listDeleted" -const accountListDisksAPI = "/restmachine/cloudapi/account/listDisks" -const accountListFlipGroupsAPI = "/restmachine/cloudapi/account/listFlipGroups" -const accountListRGAPI = "/restmachine/cloudapi/account/listRG" -const accountListTemplatesAPI = "/restmachine/cloudapi/account/listTemplates" -const accountListVinsAPI = "/restmachine/cloudapi/account/listVins" -const accountRestoreAPI = "/restmachine/cloudapi/account/restore" -const accountUpdateAPI = "/restmachine/cloudapi/account/update" -const accountUpdateUserAPI = "/restmachine/cloudapi/account/updateUser" diff --git a/internal/service/cloudapi/account/data_source_account.go b/internal/service/cloudapi/account/data_source_account.go index e796816..0407ddd 100644 --- a/internal/service/cloudapi/account/data_source_account.go +++ b/internal/service/cloudapi/account/data_source_account.go @@ -48,7 +48,7 @@ func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interf } flattenAccount(d, *acc) - d.SetId(strconv.Itoa(acc.ID)) + d.SetId(strconv.Itoa(int(acc.ID))) return nil } @@ -385,6 +385,14 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, } return res } diff --git a/internal/service/cloudapi/account/data_source_account_audits_list.go b/internal/service/cloudapi/account/data_source_account_audits_list.go index cf8fb76..6a60efb 100644 --- a/internal/service/cloudapi/account/data_source_account_audits_list.go +++ b/internal/service/cloudapi/account/data_source_account_audits_list.go @@ -38,10 +38,11 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountAuditsList(aal AccountAuditsList) []map[string]interface{} { +func flattenAccountAuditsList(aal account.ListAudits) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, aa := range aal { temp := map[string]interface{}{ diff --git a/internal/service/cloudapi/account/data_source_account_computes_list.go b/internal/service/cloudapi/account/data_source_account_computes_list.go index bbd9801..8eacd93 100644 --- a/internal/service/cloudapi/account/data_source_account_computes_list.go +++ b/internal/service/cloudapi/account/data_source_account_computes_list.go @@ -38,33 +38,34 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountComputesList(acl AccountComputesList) []map[string]interface{} { +func flattenAccountComputesList(acl account.ListComputes) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, acc := range acl { temp := map[string]interface{}{ - "account_id": acc.AccountId, + "account_id": acc.AccountID, "account_name": acc.AccountName, "cpus": acc.CPUs, "created_by": acc.CreatedBy, "created_time": acc.CreatedTime, "deleted_by": acc.DeletedBy, "deleted_time": acc.DeletedTime, - "compute_id": acc.ComputeId, + "compute_id": acc.ComputeID, "compute_name": acc.ComputeName, "ram": acc.RAM, "registered": acc.Registered, - "rg_id": acc.RgId, - "rg_name": acc.RgName, + "rg_id": acc.RGID, + "rg_name": acc.RGName, "status": acc.Status, "tech_status": acc.TechStatus, "total_disks_size": acc.TotalDisksSize, "updated_by": acc.UpdatedBy, "updated_time": acc.UpdatedTime, "user_managed": acc.UserManaged, - "vins_connected": acc.VinsConnected, + "vins_connected": acc.VINSConnected, } res = append(res, temp) } diff --git a/internal/service/cloudapi/account/data_source_account_consumed_units.go b/internal/service/cloudapi/account/data_source_account_consumed_units.go index 93b3513..acfa112 100644 --- a/internal/service/cloudapi/account/data_source_account_consumed_units.go +++ b/internal/service/cloudapi/account/data_source_account_consumed_units.go @@ -54,7 +54,7 @@ func dataSourceAccountConsumedUnitsRead(ctx context.Context, d *schema.ResourceD d.Set("cu_i", accountConsumedUnits.CUI) d.Set("cu_m", accountConsumedUnits.CUM) d.Set("cu_np", accountConsumedUnits.CUNP) - d.Set("gpu_units", accountConsumedUnits.GpuUnits) + d.Set("gpu_units", accountConsumedUnits.GPUUnits) return nil } diff --git a/internal/service/cloudapi/account/data_source_account_disks_list.go b/internal/service/cloudapi/account/data_source_account_disks_list.go index 8688f30..e528e94 100644 --- a/internal/service/cloudapi/account/data_source_account_disks_list.go +++ b/internal/service/cloudapi/account/data_source_account_disks_list.go @@ -37,17 +37,18 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountDisksList(adl AccountDisksList) []map[string]interface{} { +func flattenAccountDisksList(adl account.ListDisks) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, ad := range adl { temp := map[string]interface{}{ "disk_id": ad.ID, "disk_name": ad.Name, "pool": ad.Pool, - "sep_id": ad.SepId, + "sep_id": ad.SEPID, "shareable": ad.Shareable, "size_max": ad.SizeMax, "type": ad.Type, diff --git a/internal/service/cloudapi/account/data_source_account_flipgroups_list.go b/internal/service/cloudapi/account/data_source_account_flipgroups_list.go index 9ea55d5..369b053 100644 --- a/internal/service/cloudapi/account/data_source_account_flipgroups_list.go +++ b/internal/service/cloudapi/account/data_source_account_flipgroups_list.go @@ -38,14 +38,15 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountFlipGroupsList(afgl AccountFlipGroupsList) []map[string]interface{} { +func flattenAccountFlipGroupsList(afgl account.ListFLIPGroups) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, afg := range afgl { temp := map[string]interface{}{ - "account_id": afg.AccountId, + "account_id": afg.AccountID, "client_type": afg.ClientType, "conn_type": afg.ConnType, "created_by": afg.CreatedBy, @@ -53,7 +54,7 @@ func flattenAccountFlipGroupsList(afgl AccountFlipGroupsList) []map[string]inter "default_gw": afg.DefaultGW, "deleted_by": afg.DeletedBy, "deleted_time": afg.DeletedTime, - "desc": afg.Desc, + "desc": afg.Description, "gid": afg.GID, "guid": afg.GUID, "fg_id": afg.ID, diff --git a/internal/service/cloudapi/account/data_source_account_list.go b/internal/service/cloudapi/account/data_source_account_list.go index 2139542..cbb5d7f 100644 --- a/internal/service/cloudapi/account/data_source_account_list.go +++ b/internal/service/cloudapi/account/data_source_account_list.go @@ -38,14 +38,15 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountList(al AccountCloudApiList) []map[string]interface{} { +func flattenAccountList(al account.ListAccounts) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, acc := range al { temp := map[string]interface{}{ - "acl": flattenRgAcl(acc.Acl), + "acl": flattenRgAcl(acc.ACL), "created_time": acc.CreatedTime, "deleted_time": acc.DeletedTime, "account_id": acc.ID, @@ -58,12 +59,12 @@ func flattenAccountList(al AccountCloudApiList) []map[string]interface{} { return res } -func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} { +func flattenRgAcl(rgAcls []account.RecordACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rgAcl := range rgAcls { temp := map[string]interface{}{ "explicit": rgAcl.IsExplicit, - "guid": rgAcl.Guid, + "guid": rgAcl.GUID, "right": rgAcl.Rights, "status": rgAcl.Status, "type": rgAcl.Type, diff --git a/internal/service/cloudapi/account/data_source_account_reserved_units.go b/internal/service/cloudapi/account/data_source_account_reserved_units.go index 6fbe2a3..a323019 100644 --- a/internal/service/cloudapi/account/data_source_account_reserved_units.go +++ b/internal/service/cloudapi/account/data_source_account_reserved_units.go @@ -54,7 +54,7 @@ func dataSourceAccountReservedUnitsRead(ctx context.Context, d *schema.ResourceD d.Set("cu_i", accountReservedUnits.CUI) d.Set("cu_m", accountReservedUnits.CUM) d.Set("cu_np", accountReservedUnits.CUNP) - d.Set("gpu_units", accountReservedUnits.GpuUnits) + d.Set("gpu_units", accountReservedUnits.GPUUnits) return nil } diff --git a/internal/service/cloudapi/account/data_source_account_rg_list.go b/internal/service/cloudapi/account/data_source_account_rg_list.go index ec80816..ecad119 100644 --- a/internal/service/cloudapi/account/data_source_account_rg_list.go +++ b/internal/service/cloudapi/account/data_source_account_rg_list.go @@ -38,10 +38,11 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountRGList(argl AccountRGList) []map[string]interface{} { +func flattenAccountRGList(argl account.ListRG) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, arg := range argl { temp := map[string]interface{}{ @@ -57,7 +58,7 @@ func flattenAccountRGList(argl AccountRGList) []map[string]interface{} { "status": arg.Status, "updated_by": arg.UpdatedBy, "updated_time": arg.UpdatedTime, - "vinses": arg.Vinses, + "vinses": arg.VINSes, } res = append(res, temp) } @@ -65,7 +66,7 @@ func flattenAccountRGList(argl AccountRGList) []map[string]interface{} { } -func flattenAccRGComputes(argc AccountRGComputes) []map[string]interface{} { +func flattenAccRGComputes(argc account.RGComputes) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "started": argc.Started, @@ -75,13 +76,13 @@ func flattenAccRGComputes(argc AccountRGComputes) []map[string]interface{} { return res } -func flattenAccResourceHack(r ResourceHack) []map[string]interface{} { +func flattenAccResourceHack(r account.LimitsRG) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cpu": r.CPU, - "disksize": r.Disksize, - "extips": r.Extips, - "exttraffic": r.Exttraffic, + "disksize": r.DiskSize, + "extips": r.ExtIPs, + "exttraffic": r.ExtTraffic, "gpu": r.GPU, "ram": r.RAM, //"seps": flattenAccountSeps(r.SEPs), @@ -90,13 +91,13 @@ func flattenAccResourceHack(r ResourceHack) []map[string]interface{} { return res } -func flattenAccResourceRg(r Resource) []map[string]interface{} { +func flattenAccResourceRg(r account.Resource) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cpu": r.CPU, - "disksize": r.Disksize, - "extips": r.Extips, - "exttraffic": r.Exttraffic, + "disksize": r.DiskSize, + "extips": r.ExtIPs, + "exttraffic": r.ExtTraffic, "gpu": r.GPU, "ram": r.RAM, } @@ -104,7 +105,7 @@ func flattenAccResourceRg(r Resource) []map[string]interface{} { return res } -func flattenAccRGResources(argr AccountRGResources) []map[string]interface{} { +func flattenAccRGResources(argr account.RGResources) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "consumed": flattenAccResourceRg(argr.Consumed), diff --git a/internal/service/cloudapi/account/data_source_account_templates_list.go b/internal/service/cloudapi/account/data_source_account_templates_list.go index 529cc29..c33bc1e 100644 --- a/internal/service/cloudapi/account/data_source_account_templates_list.go +++ b/internal/service/cloudapi/account/data_source_account_templates_list.go @@ -38,16 +38,17 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountTemplatesList(atl AccountTemplatesList) []map[string]interface{} { +func flattenAccountTemplatesList(atl account.ListTemplates) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, at := range atl { temp := map[string]interface{}{ "unc_path": at.UNCPath, - "account_id": at.AccountId, - "desc": at.Desc, + "account_id": at.AccountID, + "desc": at.Description, "template_id": at.ID, "template_name": at.Name, "public": at.Public, diff --git a/internal/service/cloudapi/account/data_source_account_vins_list.go b/internal/service/cloudapi/account/data_source_account_vins_list.go index 3367249..d9b0973 100644 --- a/internal/service/cloudapi/account/data_source_account_vins_list.go +++ b/internal/service/cloudapi/account/data_source_account_vins_list.go @@ -38,14 +38,15 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountVinsList(avl AccountVinsList) []map[string]interface{} { +func flattenAccountVinsList(avl account.ListVINS) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, av := range avl { temp := map[string]interface{}{ - "account_id": av.AccountId, + "account_id": av.AccountID, "account_name": av.AccountName, "computes": av.Computes, "created_by": av.CreatedBy, @@ -56,9 +57,9 @@ func flattenAccountVinsList(avl AccountVinsList) []map[string]interface{} { "vin_id": av.ID, "vin_name": av.Name, "network": av.Network, - "pri_vnf_dev_id": av.PriVnfDevId, - "rg_id": av.RgId, - "rg_name": av.RgName, + "pri_vnf_dev_id": av.PriVNFDevID, + "rg_id": av.RGID, + "rg_name": av.RGName, "status": av.Status, "updated_by": av.UpdatedBy, "updated_time": av.UpdatedTime, diff --git a/internal/service/cloudapi/account/flattens.go b/internal/service/cloudapi/account/flattens.go index ee920c0..c043f5d 100644 --- a/internal/service/cloudapi/account/flattens.go +++ b/internal/service/cloudapi/account/flattens.go @@ -2,20 +2,19 @@ package account import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" ) -func flattenAccount(d *schema.ResourceData, acc AccountWithResources) error { +func flattenAccount(d *schema.ResourceData, acc account.RecordAccount) error { d.Set("dc_location", acc.DCLocation) d.Set("resources", flattenAccResources(acc.Resources)) d.Set("ckey", acc.CKey) - d.Set("meta", flattens.FlattenMeta(acc.Meta)) - d.Set("acl", flattenAccAcl(acc.Acl)) + d.Set("acl", flattenAccAcl(acc.ACL)) d.Set("company", acc.Company) - d.Set("companyurl", acc.CompanyUrl) + d.Set("companyurl", acc.CompanyURL) d.Set("created_by", acc.CreatedBy) d.Set("created_time", acc.CreatedTime) - d.Set("deactivation_time", acc.DeactiovationTime) + d.Set("deactivation_time", acc.DeactivationTime) d.Set("deleted_by", acc.DeletedBy) d.Set("deleted_time", acc.DeletedTime) d.Set("displayname", acc.DisplayName) @@ -24,25 +23,26 @@ func flattenAccount(d *schema.ResourceData, acc AccountWithResources) error { d.Set("account_name", acc.Name) d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) d.Set("send_access_emails", acc.SendAccessEmails) - d.Set("service_account", acc.ServiceAccount) d.Set("status", acc.Status) d.Set("updated_time", acc.UpdatedTime) d.Set("version", acc.Version) - d.Set("vins", acc.Vins) - d.Set("vinses", acc.Vinses) + d.Set("vins", acc.VINS) + d.Set("vinses", acc.VINSes) d.Set("computes", flattenAccComputes(acc.Computes)) d.Set("machines", flattenAccMachines(acc.Machines)) + d.Set("cpu_allocation_parameter", acc.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", acc.CPUAllocationRatio) if username, ok := d.GetOk("username"); ok { d.Set("username", username) } else { - d.Set("username", acc.Acl[0].UgroupID) + d.Set("username", acc.ACL[0].UgroupID) } return nil } -func flattenAccComputes(acs Computes) []map[string]interface{} { +func flattenAccComputes(acs account.Computes) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "started": acs.Started, @@ -52,7 +52,7 @@ func flattenAccComputes(acs Computes) []map[string]interface{} { return res } -func flattenAccMachines(ams Machines) []map[string]interface{} { +func flattenAccMachines(ams account.Machines) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "running": ams.Running, @@ -62,13 +62,13 @@ func flattenAccMachines(ams Machines) []map[string]interface{} { return res } -func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} { +func flattenAccAcl(acls []account.RecordACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, acls := range acls { temp := map[string]interface{}{ "can_be_deleted": acls.CanBeDeleted, "explicit": acls.IsExplicit, - "guid": acls.Guid, + "guid": acls.GUID, "right": acls.Rights, "status": acls.Status, "type": acls.Type, @@ -79,7 +79,7 @@ func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} { return res } -func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { +func flattenRgResourceLimits(rl account.ResourceLimits) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cu_c": rl.CUC, @@ -87,7 +87,7 @@ func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { "cu_i": rl.CUI, "cu_m": rl.CUM, "cu_np": rl.CUNP, - "gpu_units": rl.GpuUnits, + "gpu_units": rl.GPUUnits, } res = append(res, temp) @@ -95,7 +95,7 @@ func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { } -func flattenAccResources(r Resources) []map[string]interface{} { +func flattenAccResources(r account.Resources) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "current": flattenAccResource(r.Current), @@ -105,7 +105,7 @@ func flattenAccResources(r Resources) []map[string]interface{} { return res } -func flattenAccountSeps(seps map[string]map[string]ResourceSep) []map[string]interface{} { +func flattenAccountSeps(seps map[string]map[string]account.DiskUsage) []map[string]interface{} { res := make([]map[string]interface{}, 0) for sepKey, sepVal := range seps { for dataKey, dataVal := range sepVal { @@ -121,13 +121,13 @@ func flattenAccountSeps(seps map[string]map[string]ResourceSep) []map[string]int return res } -func flattenAccResource(r Resource) []map[string]interface{} { +func flattenAccResource(r account.Resource) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cpu": r.CPU, - "disksize": r.Disksize, - "extips": r.Extips, - "exttraffic": r.Exttraffic, + "disksize": r.DiskSize, + "extips": r.ExtIPs, + "exttraffic": r.ExtTraffic, "gpu": r.GPU, "ram": r.RAM, "seps": flattenAccountSeps(r.SEPs), diff --git a/internal/service/cloudapi/account/models.go b/internal/service/cloudapi/account/models.go deleted file mode 100644 index d05b5a7..0000000 --- a/internal/service/cloudapi/account/models.go +++ /dev/null @@ -1,277 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package account - -type AccountAclRecord struct { - IsExplicit bool `json:"explicit"` - Guid string `json:"guid"` - Rights string `json:"right"` - Status string `json:"status"` - Type string `json:"type"` - UgroupID string `json:"userGroupId"` - CanBeDeleted bool `json:"canBeDeleted"` -} - -type ResourceLimits struct { - CUC float64 `json:"CU_C"` - CUD float64 `json:"CU_D"` - CUI float64 `json:"CU_I"` - CUM float64 `json:"CU_M"` - CUNP float64 `json:"CU_NP"` - GpuUnits float64 `json:"gpu_units"` -} - -type Account struct { - DCLocation string `json:"DCLocation"` - CKey string `jspn:"_ckey"` - Meta []interface{} `json:"_meta"` - Acl []AccountAclRecord `json:"acl"` - Company string `json:"company"` - CompanyUrl string `json:"companyurl"` - CreatedBy string `jspn:"createdBy"` - CreatedTime int `json:"createdTime"` - DeactiovationTime float64 `json:"deactivationTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - DisplayName string `json:"displayname"` - GUID int `json:"guid"` - ID int `json:"id"` - Name string `json:"name"` - ResourceLimits ResourceLimits `json:"resourceLimits"` - SendAccessEmails bool `json:"sendAccessEmails"` - ServiceAccount bool `json:"serviceAccount"` - Status string `json:"status"` - UpdatedTime int `json:"updatedTime"` - Version int `json:"version"` - Vins []int `json:"vins"` -} - -type AccountList []Account - -type AccountCloudApi struct { - Acl []AccountAclRecord `json:"acl"` - CreatedTime int `json:"createdTime"` - DeletedTime int `json:"deletedTime"` - ID int `json:"id"` - Name string `json:"name"` - Status string `json:"status"` - UpdatedTime int `json:"updatedTime"` -} - -type AccountCloudApiList []AccountCloudApi - -type ResourceSep struct { - DiskSize float64 `json:"disksize"` - DiskSizeMax int `json:"disksizemax"` -} - -type Resource struct { - CPU int `json:"cpu"` - Disksize float64 `json:"disksize"` - Extips int `json:"extips"` - Exttraffic int `json:"exttraffic"` - GPU int `json:"gpu"` - RAM int `json:"ram"` - SEPs map[string]map[string]ResourceSep `json:"seps"` -} - -type Resources struct { - Current Resource `json:"Current"` - Reserved Resource `json:"Reserved"` -} - -type Computes struct { - Started int `json:"started"` - Stopped int `json:"stopped"` -} - -type Machines struct { - Running int `json:"running"` - Halted int `json:"halted"` -} - -type AccountWithResources struct { - Account - Resources Resources `json:"Resources"` - Computes Computes `json:"computes"` - Machines Machines `json:"machines"` - Vinses int `json:"vinses"` -} - -type AccountCompute struct { - AccountId int `json:"accountId"` - AccountName string `json:"accountName"` - CPUs int `json:"cpus"` - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - ComputeId int `json:"id"` - ComputeName string `json:"name"` - RAM int `json:"ram"` - Registered bool `json:"registered"` - RgId int `json:"rgId"` - RgName string `json:"rgName"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - TotalDisksSize int `json:"totalDisksSize"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` - UserManaged bool `json:"userManaged"` - VinsConnected int `json:"vinsConnected"` -} - -type AccountComputesList []AccountCompute - -type AccountDisk struct { - ID int `json:"id"` - Name string `json:"name"` - Pool string `json:"pool"` - SepId int `json:"sepId"` - Shareable bool `json:"shareable"` - SizeMax int `json:"sizeMax"` - Type string `json:"type"` -} - -type AccountDisksList []AccountDisk - -type AccountVin struct { - AccountId int `json:"accountId"` - AccountName string `json:"accountName"` - Computes int `json:"computes"` - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - ExternalIP string `json:"externalIP"` - ID int `json:"id"` - Name string `json:"name"` - Network string `json:"network"` - PriVnfDevId int `json:"priVnfDevId"` - RgId int `json:"rgId"` - RgName string `json:"rgName"` - Status string `json:"status"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` -} - -type AccountVinsList []AccountVin - -type AccountAudit struct { - Call string `json:"call"` - ResponseTime float64 `json:"responsetime"` - StatusCode int `json:"statuscode"` - Timestamp float64 `json:"timestamp"` - User string `json:"user"` -} - -type AccountAuditsList []AccountAudit - -type AccountRGComputes struct { - Started int `json:"Started"` - Stopped int `json:"Stopped"` -} - -type ResourceHack struct { - CPU int `json:"cpu"` - Disksize float64 `json:"disksize"` - Extips int `json:"extips"` - Exttraffic int `json:"exttraffic"` - GPU int `json:"gpu"` - RAM int `json:"ram"` -} - -type AccountRGResources struct { - Consumed Resource `json:"Consumed"` - Limits ResourceHack `json:"Limits"` - Reserved Resource `json:"Reserved"` -} - -type AccountRG struct { - Computes AccountRGComputes `json:"Computes"` - Resources AccountRGResources `json:"Resources"` - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - RGID int `json:"id"` - Milestones int `json:"milestones"` - RGName string `json:"name"` - Status string `json:"status"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` - Vinses int `json:"vinses"` -} - -type AccountRGList []AccountRG - -type AccountTemplate struct { - UNCPath string `json:"UNCPath"` - AccountId int `json:"accountId"` - Desc string `json:"desc"` - ID int `json:"id"` - Name string `json:"name"` - Public bool `json:"public"` - Size int `json:"size"` - Status string `json:"status"` - Type string `json:"type"` - Username string `json:"username"` -} - -type AccountTemplatesList []AccountTemplate - -type AccountFlipGroup struct { - AccountId int `json:"accountId"` - ClientType string `json:"clientType"` - ConnType string `json:"connType"` - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DefaultGW string `json:"defaultGW"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - Desc string `json:"desc"` - GID int `json:"gid"` - GUID int `json:"guid"` - ID int `json:"id"` - IP string `json:"ip"` - Milestones int `json:"milestones"` - Name string `json:"name"` - NetID int `json:"netId"` - NetType string `json:"netType"` - NetMask int `json:"netmask"` - Status string `json:"status"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` -} - -type AccountFlipGroupsList []AccountFlipGroup diff --git a/internal/service/cloudapi/account/resource_account.go b/internal/service/cloudapi/account/resource_account.go index dd5fddb..b35bfc8 100644 --- a/internal/service/cloudapi/account/resource_account.go +++ b/internal/service/cloudapi/account/resource_account.go @@ -34,13 +34,13 @@ package account import ( "context" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" @@ -50,99 +50,103 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf log.Debugf("resourceAccountCreate") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := account.CreateRequest{} - urlValues.Add("name", d.Get("account_name").(string)) - urlValues.Add("username", d.Get("username").(string)) + req.Name = d.Get("account_name").(string) + req.Username = d.Get("username").(string) if emailaddress, ok := d.GetOk("emailaddress"); ok { - urlValues.Add("emailaddress", emailaddress.(string)) + req.EmailAddress = emailaddress.(string) } if sendAccessEmails, ok := d.GetOk("send_access_emails"); ok { - urlValues.Add("sendAccessEmails", strconv.FormatBool(sendAccessEmails.(bool))) + req.SendAccessEmails = sendAccessEmails.(bool) } + if resLimits, ok := d.GetOk("resource_limits"); ok { resLimit := resLimits.([]interface{})[0] resLimitConv := resLimit.(map[string]interface{}) if resLimitConv["cu_m"] != nil { maxMemCap := int(resLimitConv["cu_m"].(float64)) if maxMemCap == 0 { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1)) + req.MaxMemoryCapacity = -1 } else { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap)) + req.MaxMemoryCapacity = int64(maxMemCap) } } if resLimitConv["cu_d"] != nil { maxDiskCap := int(resLimitConv["cu_d"].(float64)) if maxDiskCap == 0 { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1)) + req.MaxVDiskCapacity = -1 } else { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap)) + req.MaxVDiskCapacity = int64(maxDiskCap) } } if resLimitConv["cu_c"] != nil { maxCPUCap := int(resLimitConv["cu_c"].(float64)) if maxCPUCap == 0 { - urlValues.Add("maxCPUCapacity", strconv.Itoa(-1)) + req.MaxCPUCapacity = -1 } else { - urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap)) + req.MaxCPUCapacity = int64(maxCPUCap) } } if resLimitConv["cu_i"] != nil { maxNumPublicIP := int(resLimitConv["cu_i"].(float64)) if maxNumPublicIP == 0 { - urlValues.Add("maxNumPublicIP", strconv.Itoa(-1)) + req.MaxNumPublicIP = -1 } else { - urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP)) + req.MaxNumPublicIP = int64(maxNumPublicIP) } } if resLimitConv["cu_np"] != nil { maxNP := int(resLimitConv["cu_np"].(float64)) if maxNP == 0 { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1)) + req.MaxNetworkPeerTransfer = -1 } else { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP)) + req.MaxNetworkPeerTransfer = int64(maxNP) } } if resLimitConv["gpu_units"] != nil { gpuUnits := int(resLimitConv["gpu_units"].(float64)) if gpuUnits == 0 { - urlValues.Add("gpu_units", strconv.Itoa(-1)) + req.GPUUnits = -1 } else { - urlValues.Add("gpu_units", strconv.Itoa(gpuUnits)) + req.GPUUnits = int64(gpuUnits) } } } - accountId, err := c.DecortAPICall(ctx, "POST", accountCreateAPI, urlValues) + accountId, err := c.CloudAPI().Account().Create(ctx, req) if err != nil { return diag.FromErr(err) } - accIdParsed, _ := strconv.Atoi(accountId) - - d.SetId(accountId) - d.Set("account_id", accIdParsed) - - urlValues = &url.Values{} + d.SetId(strconv.FormatUint(accountId, 10)) + d.Set("account_id", accountId) if enable, ok := d.GetOk("enable"); ok { - api := accountDisableAPI + reqSwitch := account.DisableEnableRequest{ + AccountID: accountId, + } enable := enable.(bool) + if enable { - api = accountEnableAPI - } - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) - } + _, err := c.CloudAPI().Account().Enable(ctx, reqSwitch) + if err != nil { + return diag.FromErr(err) + + } else { - urlValues = &url.Values{} + _, err := c.CloudAPI().Account().Disable(ctx, reqSwitch) + if err != nil { + return diag.FromErr(err) + } + + } + } } if users, ok := d.GetOk("users"); ok { @@ -151,15 +155,16 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf if len(addedUsers) > 0 { for _, user := range addedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string))) - _, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues) + + req := account.AddUserRequest{ + AccountID: accountId, + UserID: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + } + _, err := c.CloudAPI().Account().AddUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } } @@ -187,10 +192,13 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interfac case status.Destroying: return diag.Errorf("The account is in progress with status: %s", acc.Status) case status.Deleted: - urlValues := &url.Values{} - urlValues.Add("accountId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + + req := account.RestoreRequest{ + AccountID: id, + } - _, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlValues) + _, err := c.CloudAPI().Account().Restore(ctx, req) if err != nil { return diag.FromErr(err) } @@ -216,41 +224,40 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interfac func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceAccountDelete") + c := m.(*controller.ControllerCfg) - account, err := utilityAccountCheckPresence(ctx, d, m) - if account == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) + req := account.DeleteRequest{ + AccountID: uint64(d.Get("account_id").(int)), + Permanently: d.Get("permanently").(bool), + } - _, err = c.DecortAPICall(ctx, "POST", accountDeleteAPI, urlValues) + _, err = c.CloudAPI().Account().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceAccountEdit") + log.Debugf("resourceAccountUpdate") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - acc, err := utilityAccountCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } + accountId, _ := strconv.ParseUint(d.Id(), 10, 64) + hasChanged := false switch acc.Status { @@ -260,10 +267,12 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf case status.Destroying: return diag.Errorf("The account is in progress with status: %s", acc.Status) case status.Deleted: - urlVal := &url.Values{} - urlVal.Add("accountId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlVal) + req := account.RestoreRequest{ + AccountID: accountId, + } + + _, err := c.CloudAPI().Account().Restore(ctx, req) if err != nil { return diag.FromErr(err) } @@ -283,31 +292,39 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf } if d.HasChange("enable") { - api := accountDisableAPI + reqSwitch := account.DisableEnableRequest{ + AccountID: accountId, + } enable := d.Get("enable").(bool) + if enable { - api = accountEnableAPI - } - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) + _, err := c.CloudAPI().Account().Enable(ctx, reqSwitch) + if err != nil { + return diag.FromErr(err) + + } else { + + _, err := c.CloudAPI().Account().Disable(ctx, reqSwitch) + if err != nil { + return diag.FromErr(err) + } + + } } + } - urlValues = &url.Values{} + req := account.UpdateRequest{ + AccountID: accountId, } - if d.HasChange("account_name") { - urlValues.Add("name", d.Get("account_name").(string)) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues) - if err != nil { - return diag.FromErr(err) - } + updated := false - urlValues = &url.Values{} + if d.HasChange("account_name") { + req.Name = d.Get("account_name").(string) + updated = true } + if d.HasChange("resource_limits") { resLimit := d.Get("resource_limits").([]interface{})[0] resLimitConv := resLimit.(map[string]interface{}) @@ -315,85 +332,83 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf if resLimitConv["cu_m"] != nil { maxMemCap := int(resLimitConv["cu_m"].(float64)) if maxMemCap == 0 { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1)) + req.MaxMemoryCapacity = -1 } else { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap)) + req.MaxMemoryCapacity = int64(maxMemCap) } + updated = true } if resLimitConv["cu_d"] != nil { maxDiskCap := int(resLimitConv["cu_d"].(float64)) if maxDiskCap == 0 { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1)) + req.MaxVDiskCapacity = -1 } else { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap)) + req.MaxVDiskCapacity = int64(maxDiskCap) } + updated = true } if resLimitConv["cu_c"] != nil { maxCPUCap := int(resLimitConv["cu_c"].(float64)) if maxCPUCap == 0 { - urlValues.Add("maxCPUCapacity", strconv.Itoa(-1)) + req.MaxCPUCapacity = -1 } else { - urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap)) + req.MaxCPUCapacity = int64(maxCPUCap) } - + updated = true } if resLimitConv["cu_i"] != nil { maxNumPublicIP := int(resLimitConv["cu_i"].(float64)) if maxNumPublicIP == 0 { - urlValues.Add("maxNumPublicIP", strconv.Itoa(-1)) + req.MaxNumPublicIP = -1 } else { - urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP)) + req.MaxNumPublicIP = int64(maxNumPublicIP) } - + updated = true } if resLimitConv["cu_np"] != nil { maxNP := int(resLimitConv["cu_np"].(float64)) if maxNP == 0 { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1)) + req.MaxNetworkPeerTransfer = -1 } else { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP)) + req.MaxNetworkPeerTransfer = int64(maxNP) } - + updated = true } if resLimitConv["gpu_units"] != nil { gpuUnits := int(resLimitConv["gpu_units"].(float64)) if gpuUnits == 0 { - urlValues.Add("gpu_units", strconv.Itoa(-1)) + req.GPUUnits = -1 } else { - urlValues.Add("gpu_units", strconv.Itoa(gpuUnits)) + req.GPUUnits = int64(gpuUnits) } + updated = true } - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues) - if err != nil { - return diag.FromErr(err) - } - - urlValues = &url.Values{} } if d.HasChange("send_access_emails") { - urlValues.Add("sendAccessEmails", strconv.FormatBool(d.Get("send_access_emails").(bool))) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues) + req.SendAccessEmails = d.Get("send_access_emails").(bool) + updated = true + } + + if updated { + _, err := c.CloudAPI().Account().Update(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("restore") { restore := d.Get("restore").(bool) if restore { - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlValues) - if err != nil { - return diag.FromErr(err) + if acc.Status == "DELETED" { + req := account.RestoreRequest{ + AccountID: accountId, + } + _, err := c.CloudAPI().Account().Restore(ctx, req) + if err != nil { + return diag.FromErr(err) + } } - - urlValues = &url.Values{} } } @@ -402,9 +417,9 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf addedUsers := make([]interface{}, 0) updatedUsers := make([]interface{}, 0) - old, new := d.GetChange("users") + old, new_ := d.GetChange("users") oldConv := old.([]interface{}) - newConv := new.([]interface{}) + newConv := new_.([]interface{}) for _, el := range oldConv { if !isContainsUser(newConv, el) { deletedUsers = append(deletedUsers, el) @@ -412,7 +427,15 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf } for _, el := range newConv { if !isContainsUser(oldConv, el) { - addedUsers = append(addedUsers, el) + duplicate := false + for _, user := range acc.ACL { + if user.UgroupID == el.(map[string]interface{})["user_id"].(string) { + duplicate = true + } + } + if !duplicate { + addedUsers = append(addedUsers, el) + } } else { if isChangedUser(oldConv, el) { updatedUsers = append(updatedUsers, el) @@ -423,45 +446,50 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interf if len(deletedUsers) > 0 { for _, user := range deletedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("recursivedelete", strconv.FormatBool(userConv["recursive_delete"].(bool))) - _, err := c.DecortAPICall(ctx, "POST", accountDeleteUserAPI, urlValues) + + req := account.DeleteUserRequest{ + AccountID: accountId, + UserID: userConv["user_id"].(string), + RecursiveDelete: userConv["recursive_delete"].(bool), + } + _, err := c.CloudAPI().Account().DeleteUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(addedUsers) > 0 { for _, user := range addedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string))) - _, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues) + + req := account.AddUserRequest{ + AccountID: accountId, + UserID: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + } + + _, err := c.CloudAPI().Account().AddUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(updatedUsers) > 0 { for _, user := range updatedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateUserAPI, urlValues) + + req := account.UpdateUserRequest{ + AccountID: accountId, + UserID: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + } + + _, err := c.CloudAPI().Account().UpdateUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } @@ -514,7 +542,6 @@ func resourceAccountSchemaMake() map[string]*schema.Schema { "send_access_emails": { Type: schema.TypeBool, Optional: true, - Default: true, Description: "if true send emails when a user is granted access to resources", }, "users": { @@ -613,13 +640,13 @@ func resourceAccountSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, Computed: true, }, - "meta": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, + // "meta": { + // Type: schema.TypeList, + // Computed: true, + // Elem: &schema.Schema{ + // Type: schema.TypeString, + // }, + // }, "acl": { Type: schema.TypeList, Computed: true, @@ -704,6 +731,14 @@ func resourceAccountSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, } } diff --git a/internal/service/cloudapi/account/utility_account.go b/internal/service/cloudapi/account/utility_account.go index a3832b2..092cdb7 100644 --- a/internal/service/cloudapi/account/utility_account.go +++ b/internal/service/cloudapi/account/utility_account.go @@ -34,34 +34,32 @@ package account import ( "context" - "encoding/json" - "net/url" "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*AccountWithResources, error) { - account := &AccountWithResources{} +func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.RecordAccount, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 if (strconv.Itoa(d.Get("account_id").(int))) != "0" { - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) } else { - urlValues.Add("accountId", d.Id()) + idParsed, _ := strconv.Atoi(d.Id()) + id = uint64(idParsed) } - log.Debugf("utilityAccountCheckPresence: load account") - accountRaw, err := c.DecortAPICall(ctx, "POST", accountGetAPI, urlValues) - if err != nil { - return nil, err + req := account.GetRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountRaw), &account) + log.Debugf("utilityAccountCheckPresence: load account") + account, err := c.CloudAPI().Account().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_audits_list.go b/internal/service/cloudapi/account/utility_account_audits_list.go index 9ec0a87..46eeaa6 100644 --- a/internal/service/cloudapi/account/utility_account_audits_list.go +++ b/internal/service/cloudapi/account/utility_account_audits_list.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountAuditsList, error) { - accountAuditsList := AccountAuditsList{} +func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAudits, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountAuditsListCheckPresence: load account list") - accountAuditsListRaw, err := c.DecortAPICall(ctx, "POST", accountAuditsAPI, urlValues) - if err != nil { - return nil, err + req := account.AuditsRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountAuditsListRaw), &accountAuditsList) + log.Debugf("utilityAccountAuditsListCheckPresence: load account list") + accountAuditsList, err := c.CloudAPI().Account().Audits(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_computes_list.go b/internal/service/cloudapi/account/utility_account_computes_list.go index 0296d2f..dbbab77 100644 --- a/internal/service/cloudapi/account/utility_account_computes_list.go +++ b/internal/service/cloudapi/account/utility_account_computes_list.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountComputesList, error) { - accountComputesList := AccountComputesList{} +func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListComputes, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountComputesListCheckPresence: load account list") - accountComputesListRaw, err := c.DecortAPICall(ctx, "POST", accountListComputesAPI, urlValues) - if err != nil { - return nil, err + req := account.ListComputesRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountComputesListRaw), &accountComputesList) + log.Debugf("utilityAccountComputesListCheckPresence: load account list") + accountComputesList, err := c.CloudAPI().Account().ListComputes(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_consumed_units.go b/internal/service/cloudapi/account/utility_account_consumed_units.go index 1a35373..8957c59 100644 --- a/internal/service/cloudapi/account/utility_account_consumed_units.go +++ b/internal/service/cloudapi/account/utility_account_consumed_units.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountConsumedUnitsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*ResourceLimits, error) { - accountConsumedUnits := &ResourceLimits{} +func utilityAccountConsumedUnitsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ResourceLimits, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountConsumedUnitsCheckPresence: load account list") - accountConsumedUnitsRaw, err := c.DecortAPICall(ctx, "POST", accountGetConsumedUnitsAPI, urlValues) - if err != nil { - return nil, err + req := account.GetConsumedAccountUnitsRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountConsumedUnitsRaw), accountConsumedUnits) + log.Debugf("utilityAccountConsumedUnitsCheckPresence: load account list") + accountConsumedUnits, err := c.CloudAPI().Account().GetConsumedAccountUnits(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_consumed_units_by_type.go b/internal/service/cloudapi/account/utility_account_consumed_units_by_type.go index 57b5d70..ee441c5 100644 --- a/internal/service/cloudapi/account/utility_account_consumed_units_by_type.go +++ b/internal/service/cloudapi/account/utility_account_consumed_units_by_type.go @@ -34,11 +34,10 @@ package account import ( "context" - "net/url" - "strconv" "strings" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -46,17 +45,19 @@ import ( func utilityAccountConsumedUnitsByTypeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (float64, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 + var cuType string - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("cutype", strings.ToUpper(d.Get("cu_type").(string))) + id = uint64(d.Get("account_id").(int)) + cuType = strings.ToUpper(d.Get("cu_type").(string)) - log.Debugf("utilityAccountConsumedUnitsByTypeCheckPresence") - resultRaw, err := c.DecortAPICall(ctx, "POST", accountGetConsumedUnitsByTypeAPI, urlValues) - if err != nil { - return 0, err + req := account.GetConsumedCloudUnitsByTypeRequest{ + AccountID: id, + CUType: cuType, } - result, err := strconv.ParseFloat(resultRaw, 64) + + log.Debugf("utilityAccountConsumedUnitsByTypeCheckPresence") + result, err := c.CloudAPI().Account().GetConsumedCloudUnitsByType(ctx, req) if err != nil { return 0, err } diff --git a/internal/service/cloudapi/account/utility_account_deleted_list.go b/internal/service/cloudapi/account/utility_account_deleted_list.go index 287075f..1738e82 100644 --- a/internal/service/cloudapi/account/utility_account_deleted_list.go +++ b/internal/service/cloudapi/account/utility_account_deleted_list.go @@ -34,38 +34,37 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountCloudApiList, error) { - accountDeletedList := AccountCloudApiList{} +func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAccounts, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var ( + pageVal uint64 = 0 + sizeVal uint64 = 0 + ) if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + pageVal = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + sizeVal = uint64(size.(int)) } - log.Debugf("utilityAccountDeletedListCheckPresence: load") - accountDeletedListRaw, err := c.DecortAPICall(ctx, "POST", accountListDeletedAPI, urlValues) - if err != nil { - return nil, err + req := account.ListDeletedRequest{ + Page: pageVal, + Size: sizeVal, } - err = json.Unmarshal([]byte(accountDeletedListRaw), &accountDeletedList) + log.Debugf("utilityAccountDeletedListCheckPresence: load") + accountDeletedList, err := c.CloudAPI().Account().ListDeleted(ctx, req) if err != nil { return nil, err } - return accountDeletedList, nil } diff --git a/internal/service/cloudapi/account/utility_account_disks_list.go b/internal/service/cloudapi/account/utility_account_disks_list.go index 57638a6..b6cb9ff 100644 --- a/internal/service/cloudapi/account/utility_account_disks_list.go +++ b/internal/service/cloudapi/account/utility_account_disks_list.go @@ -34,30 +34,24 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountDisksList, error) { - accountDisksList := AccountDisksList{} +func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListDisks, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountDisksListCheckPresence: load account list") - accountDisksListRaw, err := c.DecortAPICall(ctx, "POST", accountListDisksAPI, urlValues) - if err != nil { - return nil, err + req := account.ListDisksRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountDisksListRaw), &accountDisksList) + accountDisksList, err := c.CloudAPI().Account().ListDisks(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_flip_groups.go b/internal/service/cloudapi/account/utility_account_flip_groups.go index 15f5924..590c58f 100644 --- a/internal/service/cloudapi/account/utility_account_flip_groups.go +++ b/internal/service/cloudapi/account/utility_account_flip_groups.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountFlipGroupsList, error) { - accountFlipGroupsList := AccountFlipGroupsList{} +func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListFLIPGroups, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountFlipGroupsListCheckPresence") - accountFlipGroupsListRaw, err := c.DecortAPICall(ctx, "POST", accountListFlipGroupsAPI, urlValues) - if err != nil { - return nil, err + req := account.ListFLIPGroupsRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountFlipGroupsListRaw), &accountFlipGroupsList) + log.Debugf("utilityAccountFlipGroupsListCheckPresence") + accountFlipGroupsList, err := c.CloudAPI().Account().ListFLIPGroups(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_list.go b/internal/service/cloudapi/account/utility_account_list.go index 7ef83d8..1c70087 100644 --- a/internal/service/cloudapi/account/utility_account_list.go +++ b/internal/service/cloudapi/account/utility_account_list.go @@ -34,66 +34,38 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountCloudApiList, error) { - accountList := AccountCloudApiList{} +func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAccounts, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var ( + pageVal uint64 = 0 + sizeVal uint64 = 0 + ) if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + pageVal = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + sizeVal = uint64(size.(int)) } - log.Debugf("utilityAccountListCheckPresence: load account list") - accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(accountListRaw), &accountList) - if err != nil { - return nil, err - } - - return accountList, nil -} - -/*uncomment for cloudbroker -func utilityAccountListCheckPresence(d *schema.ResourceData, m interface{}) (AccountList, error) { - accountList := AccountList{} - controller := m.(*ControllerCfg) - urlValues := &url.Values{} - - if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) - } - if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req := account.ListRequest{ + Page: pageVal, + Size: sizeVal, } log.Debugf("utilityAccountListCheckPresence: load account list") - accountListRaw, err := controller.decortAPICall("POST", accountListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(accountListRaw), &accountList) + accountList, err := c.CloudAPI().Account().List(ctx, req) if err != nil { return nil, err } return accountList, nil } -*/ diff --git a/internal/service/cloudapi/account/utility_account_reserved_units.go b/internal/service/cloudapi/account/utility_account_reserved_units.go index d18f147..97b3b43 100644 --- a/internal/service/cloudapi/account/utility_account_reserved_units.go +++ b/internal/service/cloudapi/account/utility_account_reserved_units.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountReservedUnitsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*ResourceLimits, error) { - accountReservedUnits := &ResourceLimits{} +func utilityAccountReservedUnitsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.ResourceLimits, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountReservedUnitsCheckPresence: load units") - accountReservedUnitsRaw, err := c.DecortAPICall(ctx, "POST", accountGetReservedUnitsAPI, urlValues) - if err != nil { - return nil, err + req := account.GetReservedAccountUnitsRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountReservedUnitsRaw), accountReservedUnits) + log.Debugf("utilityAccountReservedUnitsCheckPresence: load units") + accountReservedUnits, err := c.CloudAPI().Account().GetReservedAccountUnits(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_rg_list.go b/internal/service/cloudapi/account/utility_account_rg_list.go index 23f2297..ee901b8 100644 --- a/internal/service/cloudapi/account/utility_account_rg_list.go +++ b/internal/service/cloudapi/account/utility_account_rg_list.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountRGList, error) { - accountRGList := AccountRGList{} +func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListRG, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountRGListCheckPresence: load account list") - accountRGListRaw, err := c.DecortAPICall(ctx, "POST", accountListRGAPI, urlValues) - if err != nil { - return nil, err + req := account.ListRGRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountRGListRaw), &accountRGList) + log.Debugf("utilityAccountRGListCheckPresence: load account list") + accountRGList, err := c.CloudAPI().Account().ListRG(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_templates_list.go b/internal/service/cloudapi/account/utility_account_templates_list.go index 6a71058..d5ae29a 100644 --- a/internal/service/cloudapi/account/utility_account_templates_list.go +++ b/internal/service/cloudapi/account/utility_account_templates_list.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountTemplatesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountTemplatesList, error) { - accountTemplatesList := AccountTemplatesList{} +func utilityAccountTemplatesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListTemplates, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountTemplatesListCheckPresence: load") - accountTemplatesListRaw, err := c.DecortAPICall(ctx, "POST", accountListTemplatesAPI, urlValues) - if err != nil { - return nil, err + req := account.ListTemplatesRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountTemplatesListRaw), &accountTemplatesList) + log.Debugf("utilityAccountTemplatesListCheckPresence: load") + accountTemplatesList, err := c.CloudAPI().Account().ListTemplates(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/account/utility_account_vins_list.go b/internal/service/cloudapi/account/utility_account_vins_list.go index 0b23120..1f2a29d 100644 --- a/internal/service/cloudapi/account/utility_account_vins_list.go +++ b/internal/service/cloudapi/account/utility_account_vins_list.go @@ -34,30 +34,26 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountVinsList, error) { - accountVinsList := AccountVinsList{} +func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + id = uint64(d.Get("account_id").(int)) - log.Debugf("utilityAccountVinsListCheckPresence: load account list") - accountVinsListRaw, err := c.DecortAPICall(ctx, "POST", accountListVinsAPI, urlValues) - if err != nil { - return nil, err + req := account.ListVINSRequest{ + AccountID: id, } - err = json.Unmarshal([]byte(accountVinsListRaw), &accountVinsList) + log.Debugf("utilityAccountVinsListCheckPresence: load account list") + accountVinsList, err := c.CloudAPI().Account().ListVINS(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/bservice/api.go b/internal/service/cloudapi/bservice/api.go deleted file mode 100644 index aaf2621..0000000 --- a/internal/service/cloudapi/bservice/api.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package bservice - -const bserviceCreateAPI = "/restmachine/cloudapi/bservice/create" -const bserviceDeleteAPI = "/restmachine/cloudapi/bservice/delete" -const bserviceDisableAPI = "/restmachine/cloudapi/bservice/disable" -const bserviceEnableAPI = "/restmachine/cloudapi/bservice/enable" -const bserviceGetAPI = "/restmachine/cloudapi/bservice/get" -const bserviceGroupAddAPI = "/restmachine/cloudapi/bservice/groupAdd" -const bserviceGroupComputeRemoveAPI = "/restmachine/cloudapi/bservice/groupComputeRemove" -const bserviceGroupGetAPI = "/restmachine/cloudapi/bservice/groupGet" -const bserviceGroupParentAddAPI = "/restmachine/cloudapi/bservice/groupParentAdd" -const bserviceGroupParentRemoveAPI = "/restmachine/cloudapi/bservice/groupParentRemove" -const bserviceGroupRemoveAPI = "/restmachine/cloudapi/bservice/groupRemove" -const bserviceGroupResizeAPI = "/restmachine/cloudapi/bservice/groupResize" -const bserviceGroupStartAPI = "/restmachine/cloudapi/bservice/groupStart" -const bserviceGroupStopAPI = "/restmachine/cloudapi/bservice/groupStop" -const bserviceGroupUpdateAPI = "/restmachine/cloudapi/bservice/groupUpdate" -const bserviceGroupUpdateExtnetAPI = "/restmachine/cloudapi/bservice/groupUpdateExtnet" -const bserviceGroupUpdateVinsAPI = "/restmachine/cloudapi/bservice/groupUpdateVins" -const bserviceListAPI = "/restmachine/cloudapi/bservice/list" -const bserviceListDeletedAPI = "/restmachine/cloudapi/bservice/listDeleted" -const bserviceRestoreAPI = "/restmachine/cloudapi/bservice/restore" -const bserviceSnapshotCreateAPI = "/restmachine/cloudapi/bservice/snapshotCreate" -const bserviceSnapshotDeleteAPI = "/restmachine/cloudapi/bservice/snapshotDelete" -const bserviceSnapshotListAPI = "/restmachine/cloudapi/bservice/snapshotList" -const bserviceSnapshotRollbackAPI = "/restmachine/cloudapi/bservice/snapshotRollback" -const bserviceStartAPI = "/restmachine/cloudapi/bservice/start" -const bserviceStopAPI = "/restmachine/cloudapi/bservice/stop" diff --git a/internal/service/cloudapi/bservice/data_source_bservice.go b/internal/service/cloudapi/bservice/data_source_bservice.go index df684f4..03fa123 100644 --- a/internal/service/cloudapi/bservice/data_source_bservice.go +++ b/internal/service/cloudapi/bservice/data_source_bservice.go @@ -47,7 +47,7 @@ func dataSourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m i return diag.FromErr(err) } - d.SetId(strconv.Itoa(bs.ID)) + d.SetId(strconv.FormatUint(bs.ID, 10)) flattenService(d, bs) @@ -77,6 +77,14 @@ func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema { Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, "compgroup_id": { Type: schema.TypeInt, Computed: true, @@ -93,10 +101,26 @@ func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stack_id": { + Type: schema.TypeInt, + Computed: true, + }, "name": { Type: schema.TypeString, Computed: true, }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, @@ -132,8 +156,33 @@ func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema { "groups": { Type: schema.TypeList, Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeInt, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "consistency": { + Type: schema.TypeBool, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, }, }, "groups_name": { diff --git a/internal/service/cloudapi/bservice/data_source_bservice_group.go b/internal/service/cloudapi/bservice/data_source_bservice_group.go index 4cd87ef..c08a443 100644 --- a/internal/service/cloudapi/bservice/data_source_bservice_group.go +++ b/internal/service/cloudapi/bservice/data_source_bservice_group.go @@ -38,6 +38,7 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) @@ -49,7 +50,7 @@ func dataSourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData id := uuid.New() d.SetId(id.String()) - d.Set("account_id", bsg.AccountId) + d.Set("account_id", bsg.AccountID) d.Set("account_name", bsg.AccountName) d.Set("computes", flattenBSGroupComputes(bsg.Computes)) d.Set("consistency", bsg.Consistency) @@ -60,10 +61,10 @@ func dataSourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData d.Set("deleted_time", bsg.DeletedTime) d.Set("disk", bsg.Disk) d.Set("driver", bsg.Driver) - d.Set("extnets", bsg.Extnets) + d.Set("extnets", bsg.ExtNets) d.Set("gid", bsg.GID) d.Set("guid", bsg.GUID) - d.Set("image_id", bsg.ImageId) + d.Set("image_id", bsg.ImageID) d.Set("milestones", bsg.Milestones) d.Set("compgroup_name", bsg.Name) d.Set("parents", bsg.Parents) @@ -71,18 +72,18 @@ func dataSourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData d.Set("rg_id", bsg.RGID) d.Set("rg_name", bsg.RGName) d.Set("role", bsg.Role) - d.Set("sep_id", bsg.SepId) + d.Set("sep_id", bsg.SEPID) d.Set("seq_no", bsg.SeqNo) d.Set("status", bsg.Status) d.Set("tech_status", bsg.TechStatus) d.Set("timeout_start", bsg.TimeoutStart) d.Set("updated_by", bsg.UpdatedBy) d.Set("updated_time", bsg.UpdatedTime) - d.Set("vinses", bsg.Vinses) + d.Set("vinses", bsg.VINSes) return nil } -func flattenBSGroupOSUsers(bsgosus BasicServiceGroupOSUsers) []map[string]interface{} { +func flattenBSGroupOSUsers(bsgosus bservice.ListOSUsers) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, bsgosu := range bsgosus { temp := map[string]interface{}{ @@ -95,12 +96,12 @@ func flattenBSGroupOSUsers(bsgosus BasicServiceGroupOSUsers) []map[string]interf return res } -func flattenBSGroupComputes(bsgcs BasicServiceGroupComputes) []map[string]interface{} { +func flattenBSGroupComputes(bsgcs bservice.ListGroupComputes) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, bsgc := range bsgcs { temp := map[string]interface{}{ "id": bsgc.ID, - "ip_addresses": bsgc.IPAdresses, + "ip_addresses": bsgc.IPAddresses, "name": bsgc.Name, "os_users": flattenBSGroupOSUsers(bsgc.OSUsers), } diff --git a/internal/service/cloudapi/bservice/data_source_bservice_list.go b/internal/service/cloudapi/bservice/data_source_bservice_list.go index 954f5bd..19ba43d 100644 --- a/internal/service/cloudapi/bservice/data_source_bservice_list.go +++ b/internal/service/cloudapi/bservice/data_source_bservice_list.go @@ -38,14 +38,15 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenBasicServiceList(bsl BasicServiceList) []map[string]interface{} { +func flattenBasicServiceList(bsl bservice.ListBasicServices) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, bs := range bsl { temp := map[string]interface{}{ - "account_id": bs.AccountId, + "account_id": bs.AccountID, "account_name": bs.AccountName, "base_domain": bs.BaseDomain, "created_by": bs.CreatedBy, @@ -57,7 +58,7 @@ func flattenBasicServiceList(bsl BasicServiceList) []map[string]interface{} { "guid": bs.GUID, "service_id": bs.ID, "service_name": bs.Name, - "parent_srv_id": bs.ParentSrvId, + "parent_srv_id": bs.ParentSrvID, "parent_srv_type": bs.ParentSrvType, "rg_id": bs.RGID, "rg_name": bs.RGName, diff --git a/internal/service/cloudapi/bservice/flattens.go b/internal/service/cloudapi/bservice/flattens.go index 962be7d..bfa496f 100644 --- a/internal/service/cloudapi/bservice/flattens.go +++ b/internal/service/cloudapi/bservice/flattens.go @@ -1,9 +1,62 @@ package bservice -import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" +) -func flattenService(d *schema.ResourceData, bs *BasicServiceExtend) { - d.Set("account_id", bs.AccountId) +func flattenResourceBasicServiceGroup(d *schema.ResourceData, bsg *bservice.RecordGroup) { + d.Set("account_id", bsg.AccountID) + d.Set("account_name", bsg.AccountName) + d.Set("computes", flattenBSGroupComputes(bsg.Computes)) + d.Set("consistency", bsg.Consistency) + d.Set("cpu", bsg.CPU) + d.Set("created_by", bsg.CreatedBy) + d.Set("created_time", bsg.CreatedTime) + d.Set("deleted_by", bsg.DeletedBy) + d.Set("deleted_time", bsg.DeletedTime) + d.Set("disk", bsg.Disk) + d.Set("driver", bsg.Driver) + d.Set("extnets", bsg.ExtNets) + d.Set("gid", bsg.GID) + d.Set("guid", bsg.GUID) + d.Set("image_id", bsg.ImageID) + d.Set("milestones", bsg.Milestones) + d.Set("compgroup_name", bsg.Name) + d.Set("compgroup_id", bsg.ID) + d.Set("parents", bsg.Parents) + d.Set("ram", bsg.RAM) + d.Set("rg_id", bsg.RGID) + d.Set("rg_name", bsg.RGName) + d.Set("role", bsg.Role) + d.Set("sep_id", bsg.SEPID) + d.Set("seq_no", bsg.SeqNo) + d.Set("status", bsg.Status) + d.Set("tech_status", bsg.TechStatus) + d.Set("timeout_start", bsg.TimeoutStart) + d.Set("updated_by", bsg.UpdatedBy) + d.Set("updated_time", bsg.UpdatedTime) + d.Set("vinses", bsg.VINSes) +} + +func flattenGroups(groups bservice.ListGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, group := range groups { + temp := map[string]interface{}{ + "computes": group.Computes, + "consistency": group.Consistency, + "id": group.ID, + "name": group.Name, + "status": group.Status, + "tech_status": group.TechStatus, + } + res = append(res, temp) + } + return res +} + +func flattenService(d *schema.ResourceData, bs *bservice.RecordBasicService) { + d.Set("account_id", bs.AccountID) d.Set("account_name", bs.AccountName) d.Set("base_domain", bs.BaseDomain) d.Set("computes", flattenBasicServiceComputes(bs.Computes)) @@ -14,15 +67,14 @@ func flattenService(d *schema.ResourceData, bs *BasicServiceExtend) { d.Set("deleted_time", bs.DeletedTime) d.Set("disk_total", bs.DiskTotal) d.Set("gid", bs.GID) - d.Set("groups", bs.Groups) - d.Set("groups_name", bs.GroupsName) + d.Set("groups", flattenGroups(bs.Groups)) d.Set("guid", bs.GUID) d.Set("milestones", bs.Milestones) d.Set("service_name", bs.Name) d.Set("service_id", bs.ID) - d.Set("parent_srv_id", bs.ParentSrvId) + d.Set("parent_srv_id", bs.ParentSrvID) d.Set("parent_srv_type", bs.ParentSrvType) - d.Set("ram_total", bs.RamTotal) + d.Set("ram_total", bs.RAMTotal) d.Set("rg_id", bs.RGID) d.Set("rg_name", bs.RGName) d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots)) @@ -35,15 +87,21 @@ func flattenService(d *schema.ResourceData, bs *BasicServiceExtend) { d.Set("user_managed", bs.UserManaged) } -func flattenBasicServiceComputes(bscs BasicServiceComputes) []map[string]interface{} { +func flattenBasicServiceComputes(bscs bservice.ListComputes) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, bsc := range bscs { temp := map[string]interface{}{ - "compgroup_id": bsc.CompGroupId, + "account_id": bsc.AccountID, + "architecture": bsc.Architecture, + "compgroup_id": bsc.CompGroupID, "compgroup_name": bsc.CompGroupName, "compgroup_role": bsc.CompGroupRole, "id": bsc.ID, "name": bsc.Name, + "rg_id": bsc.RGID, + "stack_id": bsc.StackID, + "status": bsc.Status, + "tech_status": bsc.TechStatus, } res = append(res, temp) } @@ -51,7 +109,7 @@ func flattenBasicServiceComputes(bscs BasicServiceComputes) []map[string]interfa return res } -func flattenBasicServiceSnapshots(bsrvss BasicServiceSnapshots) []map[string]interface{} { +func flattenBasicServiceSnapshots(bsrvss bservice.ListSnapshots) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, bsrvs := range bsrvss { temp := map[string]interface{}{ diff --git a/internal/service/cloudapi/bservice/models.go b/internal/service/cloudapi/bservice/models.go deleted file mode 100644 index 5de2f0d..0000000 --- a/internal/service/cloudapi/bservice/models.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package bservice - -///Structs - -type BasicServiceCompute struct { - CompGroupId int `json:"compgroupId"` - CompGroupName string `json:"compgroupName"` - CompGroupRole string `json:"compgroupRole"` - ID int `json:"id"` - Name string `json:"name"` -} - -type BasicServiceComputes []BasicServiceCompute - -type BasicServiceSnapshot struct { - GUID string `json:"guid"` - Label string `json:"label"` - Timestamp int `json:"timestamp"` - Valid bool `json:"valid"` -} - -type BasicServiceSnapshots []BasicServiceSnapshot - -type BasicService struct { - AccountId int `json:"accountId"` - AccountName string `json:"accountName"` - BaseDomain string `json:"baseDomain"` - - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - GID int `json:"gid"` - Groups []int `json:"groups"` - GUID int `json:"guid"` - ID int `json:"id"` - Name string `json:"name"` - ParentSrvId int `json:"parentSrvId"` - ParentSrvType string `json:"parentSrvType"` - RGID int `json:"rgId"` - RGName string `json:"rgName"` - SSHUser string `json:"sshUser"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` - UserManaged bool `json:"userManaged"` -} - -type BasicServiceList []BasicService - -type BasicServiceExtend struct { - BasicService - Computes BasicServiceComputes `json:"computes"` - CPUTotal int `json:"cpuTotal"` - DiskTotal int `json:"diskTotal"` - GroupsName []string `json:"groupsName"` - Milestones int `json:"milestones"` - RamTotal int `json:"ramTotal"` - Snapshots BasicServiceSnapshots `json:"snapshots"` - SSHKey string `json:"sshKey"` -} - -type BasicServiceGroupOSUser struct { - Login string `json:"login"` - Password string `json:"password"` -} - -type BasicServiceGroupOSUsers []BasicServiceGroupOSUser - -type BasicServicceGroupCompute struct { - ID int `json:"id"` - IPAdresses []string `json:"ipAddresses"` - Name string `json:"name"` - OSUsers BasicServiceGroupOSUsers `json:"osUsers"` -} - -type BasicServiceGroupComputes []BasicServicceGroupCompute - -type BasicServiceGroup struct { - AccountId int `json:"accountId"` - AccountName string `json:"accountName"` - Computes BasicServiceGroupComputes `json:"computes"` - Consistency bool `json:"consistency"` - CPU int `json:"cpu"` - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - Disk int `json:"disk"` - Driver string `json:"driver"` - Extnets []int `json:"extnets"` - GID int `json:"gid"` - GUID int `json:"guid"` - ID int `json:"id"` - ImageId int `json:"imageId"` - Milestones int `json:"milestones"` - Name string `json:"name"` - Parents []int `json:"parents"` - RAM int `json:"ram"` - RGID int `json:"rgId"` - RGName string `json:"rgName"` - Role string `json:"role"` - SepId int `json:"sepId"` - SeqNo int `json:"seqNo"` - ServiceId int `json:"serviceId"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - TimeoutStart int `json:"timeoutStart"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` - Vinses []int `json:"vinses"` -} diff --git a/internal/service/cloudapi/bservice/resource_bservice.go b/internal/service/cloudapi/bservice/resource_bservice.go index 97f3795..921c757 100644 --- a/internal/service/cloudapi/bservice/resource_bservice.go +++ b/internal/service/cloudapi/bservice/resource_bservice.go @@ -34,12 +34,12 @@ package bservice import ( "context" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" @@ -47,9 +47,8 @@ import ( func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceBasicServiceCreate") - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := bservice.CreateRequest{} haveRGID, err := existRGID(ctx, d, m) if err != nil { @@ -60,32 +59,25 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i return diag.Errorf("resourceBasicServiceCreate: can't create basic service because RGID %d is not allowed or does not exist", d.Get("rg_id").(int)) } - urlValues.Add("name", d.Get("service_name").(string)) - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) + req.Name = d.Get("service_name").(string) + req.RGID = uint64(d.Get("rg_id").(int)) if sshKey, ok := d.GetOk("ssh_key"); ok { - urlValues.Add("sshKey", sshKey.(string)) + req.SSHKey = sshKey.(string) } if sshUser, ok := d.GetOk("ssh_user"); ok { - urlValues.Add("sshUser", sshUser.(string)) + req.SSHUser = sshUser.(string) } - serviceId, err := c.DecortAPICall(ctx, "POST", bserviceCreateAPI, urlValues) + serviceId, err := c.CloudAPI().BService().Create(ctx, req) if err != nil { return diag.FromErr(err) } - serviceIdParsed, _ := strconv.Atoi(serviceId) - - d.SetId(serviceId) - d.Set("service_id", serviceIdParsed) - - diagnostics := resourceBasicServiceRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } + d.SetId(strconv.FormatUint(serviceId, 10)) + d.Set("service_id", serviceId) - return nil + return resourceBasicServiceRead(ctx, d, m) } func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -112,10 +104,20 @@ func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m int case status.Disabling: log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status) case status.Deleted: - urlVal := &url.Values{} - urlVal.Add("serviceId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := bservice.RestoreRequest{ + ServiceID: id, + } + enableReq := bservice.EnableRequest{ + ServiceID: id, + } - _, err := c.DecortAPICall(ctx, "POST", bserviceRestoreAPI, urlVal) + _, err := c.CloudAPI().BService().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + + _, err = c.CloudAPI().BService().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } @@ -146,31 +148,30 @@ func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m int func resourceBasicServiceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceBasicServiceDelete") + c := m.(*controller.ControllerCfg) - bs, err := utilityBasicServiceCheckPresence(ctx, d, m) - if bs == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityBasicServiceCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) + req := bservice.DeleteRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Permanently: d.Get("permanently").(bool), + } - _, err = c.DecortAPICall(ctx, "POST", bserviceDeleteAPI, urlValues) + _, err = c.CloudAPI().BService().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceBasicServiceEdit") + log.Debugf("resourceBasicServiceUpdate") c := m.(*controller.ControllerCfg) haveRGID, err := existRGID(ctx, d, m) @@ -201,10 +202,20 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i case status.Disabling: log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status) case status.Deleted: - urlVal := &url.Values{} - urlVal.Add("serviceId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := bservice.RestoreRequest{ + ServiceID: id, + } + enableReq := bservice.EnableRequest{ + ServiceID: id, + } - _, err := c.DecortAPICall(ctx, "POST", bserviceRestoreAPI, urlVal) + _, err := c.CloudAPI().BService().Restore(ctx, restoreReq) + if err != nil { + return diag.FromErr(err) + } + + _, err = c.CloudAPI().BService().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } @@ -228,50 +239,63 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i } } - urlValues := &url.Values{} if d.HasChange("enable") { - api := bserviceDisableAPI enable := d.Get("enable").(bool) if enable { - api = bserviceEnableAPI - } - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) + req := bservice.EnableRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) - } + _, err := c.CloudAPI().BService().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := bservice.DisableRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } - urlValues = &url.Values{} + _, err := c.CloudAPI().BService().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } } if d.HasChange("restore") { restore := d.Get("restore").(bool) if restore { - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", bserviceRestoreAPI, urlValues) + req := bservice.RestoreRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + _, err := c.CloudAPI().BService().Restore(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if d.HasChange("start") { - api := bserviceStopAPI start := d.Get("start").(bool) if start { - api = bserviceStartAPI - } - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) + req := bservice.StartRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) - } + _, err := c.CloudAPI().BService().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := bservice.StopRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } - urlValues = &url.Values{} + _, err := c.CloudAPI().BService().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } } if d.HasChange("snapshots") { @@ -300,42 +324,45 @@ func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m i if len(deletedSnapshots) > 0 { for _, snapshot := range deletedSnapshots { snapshotConv := snapshot.(map[string]interface{}) - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("label", snapshotConv["label"].(string)) - _, err := c.DecortAPICall(ctx, "POST", bserviceSnapshotDeleteAPI, urlValues) + req := bservice.SnapshotDeleteRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Label: snapshotConv["label"].(string), + } + + _, err := c.CloudAPI().BService().SnapshotDelete(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(addedSnapshots) > 0 { for _, snapshot := range addedSnapshots { snapshotConv := snapshot.(map[string]interface{}) - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("label", snapshotConv["label"].(string)) - _, err := c.DecortAPICall(ctx, "POST", bserviceSnapshotCreateAPI, urlValues) + req := bservice.SnapshotCreateRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Label: snapshotConv["label"].(string), + } + + _, err := c.CloudAPI().BService().SnapshotCreate(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(updatedSnapshots) > 0 { for _, snapshot := range updatedSnapshots { snapshotConv := snapshot.(map[string]interface{}) - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("label", snapshotConv["label"].(string)) - _, err := c.DecortAPICall(ctx, "POST", bserviceSnapshotRollbackAPI, urlValues) + req := bservice.SnapshotRollbackRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Label: snapshotConv["label"].(string), + } + + _, err := c.CloudAPI().BService().SnapshotRollback(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } @@ -402,7 +429,7 @@ func resourceBasicServiceSchemaMake() map[string]*schema.Schema { Type: schema.TypeBool, Optional: true, Default: false, - Description: "if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately", + Description: "Enable service. Enabling a service technically means setting model status of all computes and service itself to ENABLED. It does not start computes.", }, "restore": { Type: schema.TypeBool, @@ -438,6 +465,14 @@ func resourceBasicServiceSchemaMake() map[string]*schema.Schema { Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + }, "compgroup_id": { Type: schema.TypeInt, Computed: true, @@ -454,14 +489,29 @@ func resourceBasicServiceSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, + "stack_id": { + Type: schema.TypeInt, + Computed: true, + }, "name": { Type: schema.TypeString, Computed: true, }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, - "cpu_total": { Type: schema.TypeInt, Computed: true, @@ -493,15 +543,33 @@ func resourceBasicServiceSchemaMake() map[string]*schema.Schema { "groups": { Type: schema.TypeList, Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeInt, - }, - }, - "groups_name": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "computes": { + Type: schema.TypeInt, + Computed: true, + }, + "consistency": { + Type: schema.TypeBool, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + }, }, }, "guid": { diff --git a/internal/service/cloudapi/bservice/resource_bservice_group.go b/internal/service/cloudapi/bservice/resource_bservice_group.go index bf5a1b3..db53f15 100644 --- a/internal/service/cloudapi/bservice/resource_bservice_group.go +++ b/internal/service/cloudapi/bservice/resource_bservice_group.go @@ -34,14 +34,13 @@ package bservice import ( "context" - "net/url" "strconv" - "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -50,111 +49,63 @@ func resourceBasicServiceGroupCreate(ctx context.Context, d *schema.ResourceData log.Debugf("resourceBasicServiceGroupCreate") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("name", d.Get("compgroup_name").(string)) - - urlValues.Add("count", strconv.Itoa(d.Get("comp_count").(int))) - urlValues.Add("cpu", strconv.Itoa(d.Get("cpu").(int))) - urlValues.Add("ram", strconv.Itoa(d.Get("ram").(int))) - urlValues.Add("disk", strconv.Itoa(d.Get("disk").(int))) - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - urlValues.Add("driver", strings.ToUpper(d.Get("driver").(string))) + req := bservice.GroupAddRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + Name: d.Get("compgroup_name").(string), + Count: uint64(d.Get("comp_count").(int)), + CPU: uint64(d.Get("cpu").(int)), + RAM: uint64(d.Get("ram").(int)), + Disk: uint64(d.Get("disk").(int)), + ImageID: uint64(d.Get("image_id").(int)), + Driver: d.Get("driver").(string), + } if role, ok := d.GetOk("role"); ok { - urlValues.Add("role", role.(string)) + req.Role = role.(string) } if timeoutStart, ok := d.GetOk("timeout_start"); ok { - urlValues.Add("timeoutStart", strconv.Itoa(timeoutStart.(int))) + req.TimeoutStart = uint64(timeoutStart.(int)) } if vinses, ok := d.GetOk("vinses"); ok { - vs := vinses.([]interface{}) - temp := "" - l := len(vs) - for i, v := range vs { - s := strconv.Itoa(v.(int)) - if i != (l - 1) { - s += "," - } - temp = temp + s + res := []uint64{} + for _, vins := range vinses.([]interface{}) { + res = append(res, uint64(vins.(int))) } - temp = "[" + temp + "]" - urlValues.Add("vinses", temp) + + req.VINSes = res } if extnets, ok := d.GetOk("extnets"); ok { - es := extnets.([]interface{}) - temp := "" - l := len(es) - for i, e := range es { - s := strconv.Itoa(e.(int)) - if i != (l - 1) { - s += "," - } - temp = temp + s + res := []uint64{} + for _, enet := range extnets.([]interface{}) { + res = append(res, uint64(enet.(int))) } - temp = "[" + temp + "]" - urlValues.Add("extnets", temp) + + req.ExtNets = res } - compgroupId, err := c.DecortAPICall(ctx, "POST", bserviceGroupAddAPI, urlValues) + compgroupId, err := c.CloudAPI().BService().GroupAdd(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(compgroupId) + d.SetId(strconv.FormatUint(compgroupId, 10)) d.Set("compgroup_id", compgroupId) - diagnostics := resourceBasicServiceGroupRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceBasicServiceGroupRead(ctx, d, m) } func resourceBasicServiceGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceBasicServiceGroupRead") bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m) - if bsg == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } - d.Set("account_id", bsg.AccountId) - d.Set("account_name", bsg.AccountName) - d.Set("computes", flattenBSGroupComputes(bsg.Computes)) - d.Set("consistency", bsg.Consistency) - d.Set("cpu", bsg.CPU) - d.Set("created_by", bsg.CreatedBy) - d.Set("created_time", bsg.CreatedTime) - d.Set("deleted_by", bsg.DeletedBy) - d.Set("deleted_time", bsg.DeletedTime) - d.Set("disk", bsg.Disk) - d.Set("driver", bsg.Driver) - d.Set("extnets", bsg.Extnets) - d.Set("gid", bsg.GID) - d.Set("guid", bsg.GUID) - d.Set("image_id", bsg.ImageId) - d.Set("milestones", bsg.Milestones) - d.Set("compgroup_name", bsg.Name) - d.Set("compgroup_id", bsg.ID) - d.Set("parents", bsg.Parents) - d.Set("ram", bsg.RAM) - d.Set("rg_id", bsg.RGID) - d.Set("rg_name", bsg.RGName) - d.Set("role", bsg.Role) - d.Set("sep_id", bsg.SepId) - d.Set("seq_no", bsg.SeqNo) - d.Set("status", bsg.Status) - d.Set("tech_status", bsg.TechStatus) - d.Set("timeout_start", bsg.TimeoutStart) - d.Set("updated_by", bsg.UpdatedBy) - d.Set("updated_time", bsg.UpdatedTime) - d.Set("vinses", bsg.Vinses) + flattenResourceBasicServiceGroup(d, bsg) return nil } @@ -163,19 +114,17 @@ func resourceBasicServiceGroupDelete(ctx context.Context, d *schema.ResourceData log.Debugf("resourceBasicServiceGroupDelete") bsg, err := utilityBasicServiceGroupCheckPresence(ctx, d, m) - if bsg == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) + req := bservice.GroupRemoveRequest{ + ServiceID: bsg.ServiceID, + CompGroupID: bsg.ID, + } - _, err = c.DecortAPICall(ctx, "POST", bserviceGroupRemoveAPI, urlValues) + _, err = c.CloudAPI().BService().GroupRemove(ctx, req) if err != nil { return diag.FromErr(err) } @@ -184,113 +133,106 @@ func resourceBasicServiceGroupDelete(ctx context.Context, d *schema.ResourceData return nil } -func resourceBasicServiceGroupEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceBasicServiceGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceBasicServiceGroupEdit") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - if d.HasChange("comp_count") { - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) - urlValues.Add("count", strconv.Itoa(d.Get("comp_count").(int))) - urlValues.Add("mode", strings.ToUpper(d.Get("mode").(string))) - _, err := c.DecortAPICall(ctx, "POST", bserviceGroupResizeAPI, urlValues) + req := bservice.GroupResizeRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + Count: int64(d.Get("comp_count").(int)), + Mode: d.Get("mode").(string), + } + + _, err := c.CloudAPI().BService().GroupResize(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("start") { - api := bserviceGroupStopAPI start := d.Get("start").(bool) if start { - api = bserviceGroupStartAPI + req := bservice.GroupStartRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + } + + _, err := c.CloudAPI().BService().GroupStart(ctx, req) + if err != nil { + return diag.FromErr(err) + } } else { - urlValues.Add("force", strconv.FormatBool(d.Get("force_stop").(bool))) - } - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) + req := bservice.GroupStopRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + Force: d.Get("force_stop").(bool), + } - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) + _, err := c.CloudAPI().BService().GroupStop(ctx, req) + if err != nil { + return diag.FromErr(err) + } } - - urlValues = &url.Values{} } if d.HasChanges("compgroup_name", "ram", "cpu", "disk", "role") { - urlValues.Add("name", d.Get("compgroup_name").(string)) - urlValues.Add("cpu", strconv.Itoa(d.Get("cpu").(int))) - urlValues.Add("ram", strconv.Itoa(d.Get("ram").(int))) - urlValues.Add("disk", strconv.Itoa(d.Get("disk").(int))) - urlValues.Add("role", d.Get("role").(string)) - urlValues.Add("force", strconv.FormatBool(d.Get("force_update").(bool))) - - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) + req := bservice.GroupUpdateRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + Name: d.Get("compgroup_name").(string), + Role: d.Get("role").(string), + CPU: uint64(d.Get("cpu").(int)), + RAM: uint64(d.Get("ram").(int)), + Disk: uint64(d.Get("disk").(int)), + Force: d.Get("force_update").(bool), + } - _, err := c.DecortAPICall(ctx, "POST", bserviceGroupUpdateAPI, urlValues) + _, err := c.CloudAPI().BService().GroupUpdate(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("extnets") { extnets := d.Get("extnets").([]interface{}) - temp := "" - l := len(extnets) - for i, e := range extnets { - s := strconv.Itoa(e.(int)) - if i != (l - 1) { - s += ",\n" - } else { - s += "\n" - } - temp = temp + s + + res := []uint64{} + for _, enet := range extnets { + res = append(res, uint64(enet.(int))) + } + + req := bservice.GroupUpdateExtNetRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ExtNets: res, } - temp = "[" + temp + "]" - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) - urlValues.Add("extnets", temp) - _, err := c.DecortAPICall(ctx, "POST", bserviceGroupUpdateExtnetAPI, urlValues) + _, err := c.CloudAPI().BService().GroupUpdateExtNet(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("vinses") { vinses := d.Get("vinses").([]interface{}) - temp := "" - l := len(vinses) - for i, v := range vinses { - s := strconv.Itoa(v.(int)) - if i != (l - 1) { - s += ",\n" - } else { - s += "\n" - } - temp = temp + s + + res := []uint64{} + for _, vins := range vinses { + res = append(res, uint64(vins.(int))) + } + + req := bservice.GroupUpdateVINSRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + VINSes: res, } - temp = "[" + temp + "]" - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) - urlValues.Add("vinses", temp) - _, err := c.DecortAPICall(ctx, "POST", bserviceGroupUpdateVinsAPI, urlValues) + _, err := c.CloudAPI().BService().GroupUpdateVINS(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("parents") { @@ -315,31 +257,33 @@ func resourceBasicServiceGroupEdit(ctx context.Context, d *schema.ResourceData, for _, parent := range deletedParents { parentConv := parent.(int) - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) - urlValues.Add("parentId", strconv.Itoa(parentConv)) + req := bservice.GroupParentRemoveRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ParentID: uint64(parentConv), + } - _, err := c.DecortAPICall(ctx, "POST", bserviceGroupParentRemoveAPI, urlValues) + _, err := c.CloudAPI().BService().GroupParentRemove(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(addedParents) > 0 { for _, parent := range addedParents { parentConv := parent.(int) - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) - urlValues.Add("parentId", strconv.Itoa(parentConv)) - _, err := c.DecortAPICall(ctx, "POST", bserviceGroupParentAddAPI, urlValues) + + req := bservice.GroupParentAddRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ParentID: uint64(parentConv), + } + + _, err := c.CloudAPI().BService().GroupParentAdd(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } } @@ -348,16 +292,16 @@ func resourceBasicServiceGroupEdit(ctx context.Context, d *schema.ResourceData, rcs := d.Get("remove_computes").([]interface{}) if len(rcs) > 0 { for _, rc := range rcs { - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) - urlValues.Add("computeId", strconv.Itoa(rc.(int))) + req := bservice.GroupComputeRemoveRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + CompGroupID: uint64(d.Get("compgroup_id").(int)), + ComputeID: uint64(rc.(int)), + } - _, err := c.DecortAPICall(ctx, "POST", bserviceGroupComputeRemoveAPI, urlValues) + _, err := c.CloudAPI().BService().GroupComputeRemove(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } } @@ -613,7 +557,7 @@ func ResourceBasicServiceGroup() *schema.Resource { CreateContext: resourceBasicServiceGroupCreate, ReadContext: resourceBasicServiceGroupRead, - UpdateContext: resourceBasicServiceGroupEdit, + UpdateContext: resourceBasicServiceGroupUpdate, DeleteContext: resourceBasicServiceGroupDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudapi/bservice/resource_check_input_values.go b/internal/service/cloudapi/bservice/resource_check_input_values.go index 836d278..16f7e2b 100644 --- a/internal/service/cloudapi/bservice/resource_check_input_values.go +++ b/internal/service/cloudapi/bservice/resource_check_input_values.go @@ -2,41 +2,23 @@ package bservice import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - rgList := []struct { - ID int `json:"id"` - }{} + req := rg.ListRequest{} - rgListAPI := "/restmachine/cloudapi/rg/list" - - rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(rgListRaw), &rgList) + rgList, err := c.CloudAPI().RG().List(ctx, req) if err != nil { return false, err } - haveRG := false - rgId := d.Get("rg_id").(int) - for _, rg := range rgList { - if rg.ID == rgId { - haveRG = true - break - } - } + rgId := uint64(d.Get("rg_id").(int)) - return haveRG, nil + return len(rgList.FilterByID(rgId)) != 0, nil } diff --git a/internal/service/cloudapi/bservice/utility_bservicce_deleted_list.go b/internal/service/cloudapi/bservice/utility_bservicce_deleted_list.go index 8005a4f..3b321ee 100644 --- a/internal/service/cloudapi/bservice/utility_bservicce_deleted_list.go +++ b/internal/service/cloudapi/bservice/utility_bservicce_deleted_list.go @@ -34,41 +34,33 @@ package bservice import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityBasicServiceDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (BasicServiceList, error) { - basicServiceDeletedList := BasicServiceList{} +func utilityBasicServiceDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (bservice.ListBasicServices, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := bservice.ListRequest{} if accountId, ok := d.GetOk("account_id"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } if rgId, ok := d.GetOk("rg_id"); ok { - urlValues.Add("rgId", strconv.Itoa(rgId.(int))) + req.RGID = uint64(rgId.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityBasicServiceDeletedListCheckPresence") - basicServiceDeletedListRaw, err := c.DecortAPICall(ctx, "POST", bserviceListDeletedAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(basicServiceDeletedListRaw), &basicServiceDeletedList) + basicServiceDeletedList, err := c.CloudAPI().BService().ListDeleted(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/bservice/utility_bservice.go b/internal/service/cloudapi/bservice/utility_bservice.go index a61f37a..866ce6c 100644 --- a/internal/service/cloudapi/bservice/utility_bservice.go +++ b/internal/service/cloudapi/bservice/utility_bservice.go @@ -34,34 +34,31 @@ package bservice import ( "context" - "encoding/json" - "net/url" "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityBasicServiceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*BasicServiceExtend, error) { - bservice := &BasicServiceExtend{} +func utilityBasicServiceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.RecordBasicService, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 if (strconv.Itoa(d.Get("service_id").(int))) != "0" { - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) + id = uint64(d.Get("service_id").(int)) } else { - urlValues.Add("serviceId", d.Id()) + id, _ = strconv.ParseUint(d.Id(), 10, 64) } - log.Debugf("utilityBasicServiceCheckPresence") - bserviceRaw, err := c.DecortAPICall(ctx, "POST", bserviceGetAPI, urlValues) - if err != nil { - return nil, err + req := bservice.GetRequest{ + ServiceID: id, } - err = json.Unmarshal([]byte(bserviceRaw), &bservice) + log.Debugf("utilityBasicServiceCheckPresence") + bservice, err := c.CloudAPI().BService().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/bservice/utility_bservice_group.go b/internal/service/cloudapi/bservice/utility_bservice_group.go index 6adac79..47d748e 100644 --- a/internal/service/cloudapi/bservice/utility_bservice_group.go +++ b/internal/service/cloudapi/bservice/utility_bservice_group.go @@ -34,35 +34,31 @@ package bservice import ( "context" - "encoding/json" - "net/url" "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityBasicServiceGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*BasicServiceGroup, error) { - bserviceGroup := &BasicServiceGroup{} +func utilityBasicServiceGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*bservice.RecordGroup, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int))) + req := bservice.GroupGetRequest{ + ServiceID: uint64(d.Get("service_id").(int)), + } + if (strconv.Itoa(d.Get("compgroup_id").(int))) != "0" { - urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int))) + req.CompGroupID = uint64(d.Get("compgroup_id").(int)) } else { - urlValues.Add("compgroupId", d.Id()) + comGroupID, _ := strconv.ParseUint(d.Id(), 10, 64) + req.CompGroupID = comGroupID } log.Debugf("utilityBasicServiceGroupCheckPresence") - bserviceGroupRaw, err := c.DecortAPICall(ctx, "POST", bserviceGroupGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(bserviceGroupRaw), &bserviceGroup) + bserviceGroup, err := c.CloudAPI().BService().GroupGet(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/bservice/utility_bservice_list.go b/internal/service/cloudapi/bservice/utility_bservice_list.go index abeddf1..e143af7 100644 --- a/internal/service/cloudapi/bservice/utility_bservice_list.go +++ b/internal/service/cloudapi/bservice/utility_bservice_list.go @@ -34,41 +34,33 @@ package bservice import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityBasicServiceListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (BasicServiceList, error) { - basicServiceList := BasicServiceList{} +func utilityBasicServiceListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (bservice.ListBasicServices, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := bservice.ListRequest{} if accountId, ok := d.GetOk("account_id"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } if rgId, ok := d.GetOk("rg_id"); ok { - urlValues.Add("rgId", strconv.Itoa(rgId.(int))) + req.RGID = uint64(rgId.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityBasicServiceListCheckPresence") - basicServiceListRaw, err := c.DecortAPICall(ctx, "POST", bserviceListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(basicServiceListRaw), &basicServiceList) + basicServiceList, err := c.CloudAPI().BService().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/bservice/utility_bservice_snapshot_list.go b/internal/service/cloudapi/bservice/utility_bservice_snapshot_list.go index 453a879..b791f09 100644 --- a/internal/service/cloudapi/bservice/utility_bservice_snapshot_list.go +++ b/internal/service/cloudapi/bservice/utility_bservice_snapshot_list.go @@ -34,32 +34,28 @@ package bservice import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityBasicServiceSnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (BasicServiceSnapshots, error) { - basicServiceSnapshotList := BasicServiceSnapshots{} +func utilityBasicServiceSnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (bservice.ListSnapshots, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + var id uint64 if serviceId, ok := d.GetOk("service_id"); ok { - urlValues.Add("serviceId", strconv.Itoa(serviceId.(int))) + id = uint64(serviceId.(int)) } - log.Debugf("utilityBasicServiceSnapshotListCheckPresence") - basicServiceSnapshotListRaw, err := c.DecortAPICall(ctx, "POST", bserviceSnapshotListAPI, urlValues) - if err != nil { - return nil, err + req := bservice.SnapshotListRequest{ + ServiceID: id, } - err = json.Unmarshal([]byte(basicServiceSnapshotListRaw), &basicServiceSnapshotList) + log.Debugf("utilityBasicServiceSnapshotListCheckPresence") + basicServiceSnapshotList, err := c.CloudAPI().BService().SnapshotList(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/disks/api.go b/internal/service/cloudapi/disks/api.go deleted file mode 100644 index cefd9d2..0000000 --- a/internal/service/cloudapi/disks/api.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package disks - -const ( - disksCreateAPI = "/restmachine/cloudapi/disks/create" - disksGetAPI = "/restmachine/cloudapi/disks/get" - disksListAPI = "/restmachine/cloudapi/disks/list" - disksResizeAPI = "/restmachine/cloudapi/disks/resize2" - disksRenameAPI = "/restmachine/cloudapi/disks/rename" - disksDeleteAPI = "/restmachine/cloudapi/disks/delete" - disksIOLimitAPI = "/restmachine/cloudapi/disks/limitIO" - disksRestoreAPI = "/restmachine/cloudapi/disks/restore" - disksListTypesAPI = "/restmachine/cloudapi/disks/listTypes" - disksListDeletedAPI = "/restmachine/cloudapi/disks/listDeleted" - disksListUnattachedAPI = "/restmachine/cloudapi/disks/listUnattached" - - disksSnapshotDeleteAPI = "/restmachine/cloudapi/disks/snapshotDelete" - disksSnapshotRollbackAPI = "/restmachine/cloudapi/disks/snapshotRollback" - disksShareAPI = "/restmachine/cloudapi/disks/share" - disksUnshareAPI = "/restmachine/cloudapi/disks/unshare" -) diff --git a/internal/service/cloudapi/disks/data_source_disk.go b/internal/service/cloudapi/disks/data_source_disk.go index d9778df..780e4f2 100644 --- a/internal/service/cloudapi/disks/data_source_disk.go +++ b/internal/service/cloudapi/disks/data_source_disk.go @@ -34,7 +34,6 @@ package disks import ( "context" - "encoding/json" // "net/url" @@ -54,53 +53,7 @@ func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface id := uuid.New() d.SetId(id.String()) - diskAcl, _ := json.Marshal(disk.Acl) - - d.Set("account_id", disk.AccountID) - d.Set("account_name", disk.AccountName) - d.Set("acl", string(diskAcl)) - d.Set("boot_partition", disk.BootPartition) - d.Set("computes", flattenDiskComputes(disk.Computes)) - d.Set("created_time", disk.CreatedTime) - d.Set("deleted_time", disk.DeletedTime) - d.Set("desc", disk.Desc) - d.Set("destruction_time", disk.DestructionTime) - d.Set("devicename", disk.DeviceName) - d.Set("disk_path", disk.DiskPath) - d.Set("gid", disk.GridID) - d.Set("guid", disk.GUID) - d.Set("disk_id", disk.ID) - d.Set("image_id", disk.ImageID) - d.Set("images", disk.Images) - d.Set("iotune", flattenIOTune(disk.IOTune)) - d.Set("iqn", disk.IQN) - d.Set("login", disk.Login) - d.Set("milestones", disk.Milestones) - d.Set("disk_name", disk.Name) - d.Set("order", disk.Order) - d.Set("params", disk.Params) - d.Set("parent_id", disk.ParentId) - d.Set("passwd", disk.Passwd) - d.Set("pci_slot", disk.PciSlot) - d.Set("pool", disk.Pool) - d.Set("present_to", disk.PresentTo) - d.Set("purge_attempts", disk.PurgeAttempts) - d.Set("purge_time", disk.PurgeTime) - d.Set("reality_device_number", disk.RealityDeviceNumber) - d.Set("reference_id", disk.ReferenceId) - d.Set("res_id", disk.ResID) - d.Set("res_name", disk.ResName) - d.Set("role", disk.Role) - d.Set("sep_id", disk.SepID) - d.Set("sep_type", disk.SepType) - d.Set("shareable", disk.Shareable) - d.Set("size_max", disk.SizeMax) - d.Set("size_used", disk.SizeUsed) - d.Set("snapshots", flattenDiskSnapshotList(disk.Snapshots)) - d.Set("status", disk.Status) - d.Set("tech_status", disk.TechStatus) - d.Set("type", disk.Type) - d.Set("vmid", disk.VMID) + flattenDisk(d, disk) return nil } @@ -126,11 +79,11 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, Computed: true, }, - "boot_partition": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of disk partitions", - }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, "computes": { Type: schema.TypeList, Computed: true, @@ -172,21 +125,21 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema { Computed: true, Description: "Name of the device", }, - "disk_path": { - Type: schema.TypeString, - Computed: true, - Description: "Disk path", - }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, "gid": { Type: schema.TypeInt, Computed: true, Description: "ID of the grid (platform)", }, - "guid": { - Type: schema.TypeInt, - Computed: true, - Description: "Disk ID on the storage side", - }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, "image_id": { Type: schema.TypeInt, Computed: true, @@ -273,21 +226,21 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema { }, }, }, - "iqn": { - Type: schema.TypeString, - Computed: true, - Description: "Disk IQN", - }, - "login": { - Type: schema.TypeString, - Computed: true, - Description: "Login to access the disk", - }, - "milestones": { - Type: schema.TypeInt, - Computed: true, - Description: "Milestones", - }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + // "milestones": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Milestones", + // }, "disk_name": { Type: schema.TypeString, Computed: true, @@ -308,11 +261,11 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema { Computed: true, Description: "ID of the parent disk", }, - "passwd": { - Type: schema.TypeString, - Computed: true, - Description: "Password to access the disk", - }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, "pci_slot": { Type: schema.TypeInt, Computed: true, @@ -330,26 +283,26 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, }, }, - "purge_attempts": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of deletion attempts", - }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, "purge_time": { Type: schema.TypeInt, Computed: true, Description: "Time of the last deletion attempt", }, - "reality_device_number": { - Type: schema.TypeInt, - Computed: true, - Description: "Reality device number", - }, - "reference_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the reference to the disk", - }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, "res_id": { Type: schema.TypeString, Computed: true, diff --git a/internal/service/cloudapi/disks/data_source_disk_list.go b/internal/service/cloudapi/disks/data_source_disk_list.go index 3bfee4f..b6d6d82 100644 --- a/internal/service/cloudapi/disks/data_source_disk_list.go +++ b/internal/service/cloudapi/disks/data_source_disk_list.go @@ -42,7 +42,7 @@ import ( ) func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - diskList, err := utilityDiskListCheckPresence(ctx, d, m, disksListAPI) + diskList, err := utilityDiskListCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } @@ -95,11 +95,11 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, Computed: true, }, - "boot_partition": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of disk partitions", - }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, "computes": { Type: schema.TypeList, Computed: true, @@ -141,21 +141,21 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema { Computed: true, Description: "Name of the device", }, - "disk_path": { - Type: schema.TypeString, - Computed: true, - Description: "Disk path", - }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, "gid": { Type: schema.TypeInt, Computed: true, Description: "ID of the grid (platform)", }, - "guid": { - Type: schema.TypeInt, - Computed: true, - Description: "Disk ID on the storage side", - }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, "disk_id": { Type: schema.TypeInt, Computed: true, @@ -247,16 +247,16 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema { }, }, }, - "iqn": { - Type: schema.TypeString, - Computed: true, - Description: "Disk IQN", - }, - "login": { - Type: schema.TypeString, - Computed: true, - Description: "Login to access the disk", - }, + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, "machine_id": { Type: schema.TypeInt, Computed: true, @@ -267,11 +267,11 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema { Computed: true, Description: "Machine name", }, - "milestones": { - Type: schema.TypeInt, - Computed: true, - Description: "Milestones", - }, + // "milestones": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Milestones", + // }, "disk_name": { Type: schema.TypeString, Computed: true, @@ -292,11 +292,11 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema { Computed: true, Description: "ID of the parent disk", }, - "passwd": { - Type: schema.TypeString, - Computed: true, - Description: "Password to access the disk", - }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, "pci_slot": { Type: schema.TypeInt, Computed: true, @@ -314,26 +314,26 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, }, }, - "purge_attempts": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of deletion attempts", - }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, "purge_time": { Type: schema.TypeInt, Computed: true, Description: "Time of the last deletion attempt", }, - "reality_device_number": { - Type: schema.TypeInt, - Computed: true, - Description: "Reality device number", - }, - "reference_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the reference to the disk", - }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, "res_id": { Type: schema.TypeString, Computed: true, diff --git a/internal/service/cloudapi/disks/data_source_disk_list_types_detailed.go b/internal/service/cloudapi/disks/data_source_disk_list_types_detailed.go index efc8a88..e46e274 100644 --- a/internal/service/cloudapi/disks/data_source_disk_list_types_detailed.go +++ b/internal/service/cloudapi/disks/data_source_disk_list_types_detailed.go @@ -41,24 +41,26 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenDiskListTypesDetailed(tld TypesDetailedList) []map[string]interface{} { +func flattenDiskListTypesDetailed(tld []interface{}) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, typeListDetailed := range tld { + toMap := typeListDetailed.(map[string]interface{}) temp := map[string]interface{}{ - "pools": flattenListTypesDetailedPools(typeListDetailed.Pools), - "sep_id": typeListDetailed.SepID, + "pools": flattenListTypesDetailedPools(toMap["pools"].([]interface{})), + "sep_id": toMap["sepId"].(float64), } res = append(res, temp) } return res } -func flattenListTypesDetailedPools(pools PoolList) []interface{} { +func flattenListTypesDetailedPools(pools []interface{}) []interface{} { res := make([]interface{}, 0) for _, pool := range pools { + toMap := pool.(map[string]interface{}) temp := map[string]interface{}{ - "name": pool.Name, - "types": pool.Types, + "name": toMap["name"].(string), + "types": toMap["types"].([]interface{}), } res = append(res, temp) } diff --git a/internal/service/cloudapi/disks/data_source_disk_list_unattached.go b/internal/service/cloudapi/disks/data_source_disk_list_unattached.go index 556598d..509de1e 100644 --- a/internal/service/cloudapi/disks/data_source_disk_list_unattached.go +++ b/internal/service/cloudapi/disks/data_source_disk_list_unattached.go @@ -34,92 +34,13 @@ package disks import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" - log "github.com/sirupsen/logrus" ) -func utilityDiskListUnattachedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (UnattachedList, error) { - unattachedList := UnattachedList{} - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - if accountId, ok := d.GetOk("accountId"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) - } - - log.Debugf("utilityDiskListUnattachedCheckPresence: load disk Unattached list") - unattachedListRaw, err := c.DecortAPICall(ctx, "POST", disksListUnattachedAPI, urlValues) - if err != nil { - return nil, err - } - err = json.Unmarshal([]byte(unattachedListRaw), &unattachedList) - if err != nil { - return nil, err - } - return unattachedList, nil -} - -func flattenDiskListUnattached(ul UnattachedList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, unattachedDisk := range ul { - unattachedDiskAcl, _ := json.Marshal(unattachedDisk.Acl) - tmp := map[string]interface{}{ - "_ckey": unattachedDisk.Ckey, - "_meta": flattens.FlattenMeta(unattachedDisk.Meta), - "account_id": unattachedDisk.AccountID, - "account_name": unattachedDisk.AccountName, - "acl": string(unattachedDiskAcl), - "boot_partition": unattachedDisk.BootPartition, - "created_time": unattachedDisk.CreatedTime, - "deleted_time": unattachedDisk.DeletedTime, - "desc": unattachedDisk.Desc, - "destruction_time": unattachedDisk.DestructionTime, - "disk_path": unattachedDisk.DiskPath, - "gid": unattachedDisk.GridID, - "guid": unattachedDisk.GUID, - "disk_id": unattachedDisk.ID, - "image_id": unattachedDisk.ImageID, - "images": unattachedDisk.Images, - "iotune": flattenIOTune(unattachedDisk.IOTune), - "iqn": unattachedDisk.IQN, - "login": unattachedDisk.Login, - "milestones": unattachedDisk.Milestones, - "disk_name": unattachedDisk.Name, - "order": unattachedDisk.Order, - "params": unattachedDisk.Params, - "parent_id": unattachedDisk.ParentID, - "passwd": unattachedDisk.Passwd, - "pci_slot": unattachedDisk.PciSlot, - "pool": unattachedDisk.Pool, - "purge_attempts": unattachedDisk.PurgeAttempts, - "purge_time": unattachedDisk.PurgeTime, - "reality_device_number": unattachedDisk.RealityDeviceNumber, - "reference_id": unattachedDisk.ReferenceID, - "res_id": unattachedDisk.ResID, - "res_name": unattachedDisk.ResName, - "role": unattachedDisk.Role, - "sep_id": unattachedDisk.SepID, - "size_max": unattachedDisk.SizeMax, - "size_used": unattachedDisk.SizeUsed, - "snapshots": flattenDiskSnapshotList(unattachedDisk.Snapshots), - "status": unattachedDisk.Status, - "tech_status": unattachedDisk.TechStatus, - "type": unattachedDisk.Type, - "vmid": unattachedDisk.VMID, - } - res = append(res, tmp) - } - return res -} - func dataSourceDiskListUnattachedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { diskListUnattached, err := utilityDiskListUnattachedCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudapi/disks/data_source_disk_snapshot.go b/internal/service/cloudapi/disks/data_source_disk_snapshot.go index a9ed76f..4140009 100644 --- a/internal/service/cloudapi/disks/data_source_disk_snapshot.go +++ b/internal/service/cloudapi/disks/data_source_disk_snapshot.go @@ -38,21 +38,19 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) func dataSourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { disk, err := utilityDiskCheckPresence(ctx, d, m) - if disk == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } - snapshots := disk.Snapshots - snapshot := Snapshot{} + + var snapshot disks.ItemSnapshot label := d.Get("label").(string) - for _, sn := range snapshots { + for _, sn := range disk.Snapshots { if label == sn.Label { snapshot = sn break @@ -64,11 +62,9 @@ func dataSourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m i id := uuid.New() d.SetId(id.String()) - d.Set("timestamp", snapshot.TimeStamp) - d.Set("guid", snapshot.Guid) - d.Set("res_id", snapshot.ResId) - d.Set("snap_set_guid", snapshot.SnapSetGuid) - d.Set("snap_set_time", snapshot.SnapSetTime) + + flattenDiskSnapshot(d, snapshot) + return nil } diff --git a/internal/service/cloudapi/disks/data_source_disk_snapshot_list.go b/internal/service/cloudapi/disks/data_source_disk_snapshot_list.go index b196d69..d1dbe06 100644 --- a/internal/service/cloudapi/disks/data_source_disk_snapshot_list.go +++ b/internal/service/cloudapi/disks/data_source_disk_snapshot_list.go @@ -43,11 +43,8 @@ import ( func dataSourceDiskSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { disk, err := utilityDiskCheckPresence(ctx, d, m) - if disk == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } id := uuid.New() diff --git a/internal/service/cloudapi/disks/data_source_list_deleted.go b/internal/service/cloudapi/disks/data_source_list_deleted.go index f8bec6e..caeef49 100644 --- a/internal/service/cloudapi/disks/data_source_list_deleted.go +++ b/internal/service/cloudapi/disks/data_source_list_deleted.go @@ -42,7 +42,7 @@ import ( ) func dataSourceDiskListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - diskList, err := utilityDiskListCheckPresence(ctx, d, m, disksListDeletedAPI) + diskList, err := utilityDiskListCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudapi/disks/flattens.go b/internal/service/cloudapi/disks/flattens.go index d8eb8f2..08bffd9 100644 --- a/internal/service/cloudapi/disks/flattens.go +++ b/internal/service/cloudapi/disks/flattens.go @@ -4,43 +4,106 @@ import ( "encoding/json" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) -func flattenDisk(d *schema.ResourceData, disk Disk) { - diskAcl, _ := json.Marshal(disk.Acl) +func flattenDiskSnapshot(d *schema.ResourceData, snapshot disks.ItemSnapshot) { + d.Set("timestamp", snapshot.TimeStamp) + d.Set("guid", snapshot.GUID) + d.Set("res_id", snapshot.ResID) + d.Set("snap_set_guid", snapshot.SnapSetGUID) + d.Set("snap_set_time", snapshot.SnapSetTime) +} + +func flattenDiskListUnattached(ul disks.ListDisksUnattached) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, unattachedDisk := range ul { + unattachedDiskAcl, _ := json.Marshal(unattachedDisk.ACL) + tmp := map[string]interface{}{ + "_ckey": unattachedDisk.CKey, + "_meta": flattens.FlattenMeta(unattachedDisk.Meta), + "account_id": unattachedDisk.AccountID, + "account_name": unattachedDisk.AccountName, + "acl": string(unattachedDiskAcl), + "boot_partition": unattachedDisk.BootPartition, + "created_time": unattachedDisk.CreatedTime, + "deleted_time": unattachedDisk.DeletedTime, + "desc": unattachedDisk.Description, + "destruction_time": unattachedDisk.DestructionTime, + "disk_path": unattachedDisk.DiskPath, + "gid": unattachedDisk.GID, + "guid": unattachedDisk.GUID, + "disk_id": unattachedDisk.ID, + "image_id": unattachedDisk.ImageID, + "images": unattachedDisk.Images, + "iotune": flattenIOTune(unattachedDisk.IOTune), + "iqn": unattachedDisk.IQN, + "login": unattachedDisk.Login, + "milestones": unattachedDisk.Milestones, + "disk_name": unattachedDisk.Name, + "order": unattachedDisk.Order, + "params": unattachedDisk.Params, + "parent_id": unattachedDisk.ParentID, + "passwd": unattachedDisk.Password, + "pci_slot": unattachedDisk.PCISlot, + "pool": unattachedDisk.Pool, + "purge_attempts": unattachedDisk.PurgeAttempts, + "purge_time": unattachedDisk.PurgeTime, + "reality_device_number": unattachedDisk.RealityDeviceNumber, + "reference_id": unattachedDisk.ReferenceID, + "res_id": unattachedDisk.ResID, + "res_name": unattachedDisk.ResName, + "role": unattachedDisk.Role, + "sep_id": unattachedDisk.SEPID, + "size_max": unattachedDisk.SizeMax, + "size_used": unattachedDisk.SizeUsed, + "snapshots": flattenDiskSnapshotList(unattachedDisk.Snapshots), + "status": unattachedDisk.Status, + "tech_status": unattachedDisk.TechStatus, + "type": unattachedDisk.Type, + "vmid": unattachedDisk.VMID, + } + res = append(res, tmp) + } + return res +} + +func flattenDisk(d *schema.ResourceData, disk *disks.RecordDisk) { + diskAcl, _ := json.Marshal(disk.ACL) d.Set("account_id", disk.AccountID) d.Set("account_name", disk.AccountName) d.Set("acl", string(diskAcl)) - d.Set("boot_partition", disk.BootPartition) + // d.Set("boot_partition", disk.BootPartition) d.Set("computes", flattenDiskComputes(disk.Computes)) d.Set("created_time", disk.CreatedTime) d.Set("deleted_time", disk.DeletedTime) - d.Set("desc", disk.Desc) + d.Set("desc", disk.Description) d.Set("destruction_time", disk.DestructionTime) d.Set("devicename", disk.DeviceName) - d.Set("disk_path", disk.DiskPath) - d.Set("gid", disk.GridID) - d.Set("guid", disk.GUID) + // d.Set("disk_path", disk.DiskPath) + d.Set("gid", disk.GID) + // d.Set("guid", disk.GUID) d.Set("disk_id", disk.ID) d.Set("image_id", disk.ImageID) d.Set("images", disk.Images) d.Set("iotune", flattenIOTune(disk.IOTune)) - d.Set("iqn", disk.IQN) - d.Set("login", disk.Login) - d.Set("milestones", disk.Milestones) + // d.Set("iqn", disk.IQN) + // d.Set("login", disk.Login) + // d.Set("milestones", disk.Milestones) d.Set("disk_name", disk.Name) d.Set("order", disk.Order) d.Set("params", disk.Params) - d.Set("parent_id", disk.ParentId) - d.Set("passwd", disk.Passwd) - d.Set("pci_slot", disk.PciSlot) + d.Set("parent_id", disk.ParentID) + // d.Set("passwd", disk.Passwd) + d.Set("pci_slot", disk.PCISlot) d.Set("pool", disk.Pool) d.Set("present_to", disk.PresentTo) - d.Set("purge_attempts", disk.PurgeAttempts) + // d.Set("purge_attempts", disk.PurgeAttempts) d.Set("purge_time", disk.PurgeTime) - d.Set("reality_device_number", disk.RealityDeviceNumber) - d.Set("reference_id", disk.ReferenceId) + // d.Set("reality_device_number", disk.RealityDeviceNumber) + // d.Set("reference_id", disk.ReferenceID) d.Set("res_id", disk.ResID) d.Set("res_name", disk.ResName) d.Set("role", disk.Role) @@ -56,14 +119,14 @@ func flattenDisk(d *schema.ResourceData, disk Disk) { d.Set("vmid", disk.VMID) } -func flattenDiskSnapshotList(sl SnapshotList) []interface{} { +func flattenDiskSnapshotList(sl disks.ListSnapshots) []interface{} { res := make([]interface{}, 0) for _, snapshot := range sl { temp := map[string]interface{}{ - "guid": snapshot.Guid, + "guid": snapshot.GUID, "label": snapshot.Label, - "res_id": snapshot.ResId, - "snap_set_guid": snapshot.SnapSetGuid, + "res_id": snapshot.ResID, + "snap_set_guid": snapshot.SnapSetGUID, "snap_set_time": snapshot.SnapSetTime, "timestamp": snapshot.TimeStamp, } @@ -73,80 +136,70 @@ func flattenDiskSnapshotList(sl SnapshotList) []interface{} { return res } -func flattenDiskList(dl DisksList) []map[string]interface{} { +func flattenDiskList(dl disks.ListDisks) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, disk := range dl { - diskAcl, _ := json.Marshal(disk.Acl) + diskAcl, _ := json.Marshal(disk.ACL) temp := map[string]interface{}{ - "account_id": disk.AccountID, - "account_name": disk.AccountName, - "acl": string(diskAcl), - "computes": flattenDiskComputes(disk.Computes), - "boot_partition": disk.BootPartition, - "created_time": disk.CreatedTime, - "deleted_time": disk.DeletedTime, - "desc": disk.Desc, - "destruction_time": disk.DestructionTime, - "devicename": disk.DeviceName, - "disk_path": disk.DiskPath, - "gid": disk.GridID, - "guid": disk.GUID, - "disk_id": disk.ID, - "image_id": disk.ImageID, - "images": disk.Images, - "iotune": flattenIOTune(disk.IOTune), - "iqn": disk.IQN, - "login": disk.Login, - "machine_id": disk.MachineId, - "machine_name": disk.MachineName, - "milestones": disk.Milestones, - "disk_name": disk.Name, - "order": disk.Order, - "params": disk.Params, - "parent_id": disk.ParentId, - "passwd": disk.Passwd, - "pci_slot": disk.PciSlot, - "pool": disk.Pool, - "present_to": disk.PresentTo, - "purge_attempts": disk.PurgeAttempts, - "purge_time": disk.PurgeTime, - "reality_device_number": disk.RealityDeviceNumber, - "reference_id": disk.ReferenceId, - "res_id": disk.ResID, - "res_name": disk.ResName, - "role": disk.Role, - "sep_id": disk.SepID, - "sep_type": disk.SepType, - "shareable": disk.Shareable, - "size_max": disk.SizeMax, - "size_used": disk.SizeUsed, - "snapshots": flattenDiskSnapshotList(disk.Snapshots), - "status": disk.Status, - "tech_status": disk.TechStatus, - "type": disk.Type, - "vmid": disk.VMID, + "account_id": disk.AccountID, + "account_name": disk.AccountName, + "acl": string(diskAcl), + "computes": flattenDiskComputes(disk.Computes), + "created_time": disk.CreatedTime, + "deleted_time": disk.DeletedTime, + "desc": disk.Description, + "destruction_time": disk.DestructionTime, + "devicename": disk.DeviceName, + "gid": disk.GID, + "disk_id": disk.ID, + "image_id": disk.ImageID, + "images": disk.Images, + "iotune": flattenIOTune(disk.IOTune), + "machine_id": disk.MachineID, + "machine_name": disk.MachineName, + "disk_name": disk.Name, + "order": disk.Order, + "params": disk.Params, + "parent_id": disk.ParentID, + "pci_slot": disk.PCISlot, + "pool": disk.Pool, + "present_to": disk.PresentTo, + "purge_time": disk.PurgeTime, + "res_id": disk.ResID, + "res_name": disk.ResName, + "role": disk.Role, + "sep_id": disk.SepID, + "sep_type": disk.SepType, + "shareable": disk.Shareable, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "snapshots": flattenDiskSnapshotList(disk.Snapshots), + "status": disk.Status, + "tech_status": disk.TechStatus, + "type": disk.Type, + "vmid": disk.VMID, } res = append(res, temp) } return res } -func flattenIOTune(iot IOTune) []map[string]interface{} { +func flattenIOTune(iot disks.IOTune) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "read_bytes_sec": iot.ReadBytesSec, "read_bytes_sec_max": iot.ReadBytesSecMax, - "read_iops_sec": iot.ReadIopsSec, - "read_iops_sec_max": iot.ReadIopsSecMax, - "size_iops_sec": iot.SizeIopsSec, + "read_iops_sec": iot.ReadIOPSSec, + "read_iops_sec_max": iot.ReadIOPSSecMax, + "size_iops_sec": iot.SizeIOPSSec, "total_bytes_sec": iot.TotalBytesSec, "total_bytes_sec_max": iot.TotalBytesSecMax, - "total_iops_sec": iot.TotalIopsSec, - "total_iops_sec_max": iot.TotalIopsSecMax, + "total_iops_sec": iot.TotalIOPSSec, + "total_iops_sec_max": iot.TotalIOPSSecMax, "write_bytes_sec": iot.WriteBytesSec, "write_bytes_sec_max": iot.WriteBytesSecMax, - "write_iops_sec": iot.WriteIopsSec, - "write_iops_sec_max": iot.WriteIopsSecMax, + "write_iops_sec": iot.WriteIOPSSec, + "write_iops_sec_max": iot.WriteIOPSSecMax, } res = append(res, temp) diff --git a/internal/service/cloudapi/disks/models.go b/internal/service/cloudapi/disks/models.go deleted file mode 100644 index 1ad2416..0000000 --- a/internal/service/cloudapi/disks/models.go +++ /dev/null @@ -1,181 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package disks - -type Disk struct { - Acl map[string]interface{} `json:"acl"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - BootPartition int `json:"bootPartition"` - Computes map[string]string `json:"computes"` - CreatedTime uint64 `json:"creationTime"` - DeletedTime uint64 `json:"deletionTime"` - DeviceName string `json:"devicename"` - Desc string `json:"desc"` - DestructionTime uint64 `json:"destructionTime"` - DiskPath string `json:"diskPath"` - GridID int `json:"gid"` - GUID int `json:"guid"` - ID uint `json:"id"` - ImageID int `json:"imageId"` - Images []int `json:"images"` - IOTune IOTune `json:"iotune"` - IQN string `json:"iqn"` - Login string `json:"login"` - Name string `json:"name"` - MachineId int `json:"machineId"` - MachineName string `json:"machineName"` - Milestones uint64 `json:"milestones"` - Order int `json:"order"` - Params string `json:"params"` - Passwd string `json:"passwd"` - ParentId int `json:"parentId"` - PciSlot int `json:"pciSlot"` - Pool string `json:"pool"` - PresentTo []int `json:"presentTo"` - PurgeTime uint64 `json:"purgeTime"` - PurgeAttempts uint64 `json:"purgeAttempts"` - RealityDeviceNumber int `json:"realityDeviceNumber"` - ReferenceId string `json:"referenceId"` - ResID string `json:"resId"` - ResName string `json:"resName"` - Role string `json:"role"` - SepType string `json:"sepType"` - Shareable bool `json:"shareable"` - SepID int `json:"sepId"` // NOTE: absent from compute/get output - SizeMax int `json:"sizeMax"` - SizeUsed float64 `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space - Snapshots []Snapshot `json:"snapshots"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` - UpdateBy uint64 `json:"updateBy"` - VMID int `json:"vmid"` -} - -type Snapshot struct { - Guid string `json:"guid"` - Label string `json:"label"` - ResId string `json:"resId"` - SnapSetGuid string `json:"snapSetGuid"` - SnapSetTime uint64 `json:"snapSetTime"` - TimeStamp uint64 `json:"timestamp"` -} - -type SnapshotList []Snapshot - -type DisksList []Disk - -type IOTune struct { - ReadBytesSec int `json:"read_bytes_sec"` - ReadBytesSecMax int `json:"read_bytes_sec_max"` - ReadIopsSec int `json:"read_iops_sec"` - ReadIopsSecMax int `json:"read_iops_sec_max"` - SizeIopsSec int `json:"size_iops_sec"` - TotalBytesSec int `json:"total_bytes_sec"` - TotalBytesSecMax int `json:"total_bytes_sec_max"` - TotalIopsSec int `json:"total_iops_sec"` - TotalIopsSecMax int `json:"total_iops_sec_max"` - WriteBytesSec int `json:"write_bytes_sec"` - WriteBytesSecMax int `json:"write_bytes_sec_max"` - WriteIopsSec int `json:"write_iops_sec"` - WriteIopsSecMax int `json:"write_iops_sec_max"` -} - -type Pool struct { - Name string `json:"name"` - Types []string `json:"types"` -} - -type PoolList []Pool - -type TypeDetailed struct { - Pools []Pool `json:"pools"` - SepID int `json:"sepId"` -} - -type TypesDetailedList []TypeDetailed - -type TypesList []string - -type Unattached struct { - Ckey string `json:"_ckey"` - Meta []interface{} `json:"_meta"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - Acl map[string]interface{} `json:"acl"` - BootPartition int `json:"bootPartition"` - CreatedTime int `json:"createdTime"` - DeletedTime int `json:"deletedTime"` - Desc string `json:"desc"` - DestructionTime int `json:"destructionTime"` - DiskPath string `json:"diskPath"` - GridID int `json:"gid"` - GUID int `json:"guid"` - ID int `json:"id"` - ImageID int `json:"imageId"` - Images []int `json:"images"` - IOTune IOTune `json:"iotune"` - IQN string `json:"iqn"` - Login string `json:"login"` - Milestones int `json:"milestones"` - Name string `json:"name"` - Order int `json:"order"` - Params string `json:"params"` - ParentID int `json:"parentId"` - Passwd string `json:"passwd"` - PciSlot int `json:"pciSlot"` - Pool string `json:"pool"` - PurgeAttempts int `json:"purgeAttempts"` - PurgeTime int `json:"purgeTime"` - RealityDeviceNumber int `json:"realityDeviceNumber"` - ReferenceID string `json:"referenceId"` - ResID string `json:"resId"` - ResName string `json:"resName"` - Role string `json:"role"` - SepID int `json:"sepId"` - SizeMax int `json:"sizeMax"` - SizeUsed float64 `json:"sizeUsed"` - Snapshots []Snapshot `json:"snapshots"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` - VMID int `json:"vmid"` -} - -type UnattachedList []Unattached - -type Pair struct { - intPort int - extPortStart int -} diff --git a/internal/service/cloudapi/disks/resource_check_input_values.go b/internal/service/cloudapi/disks/resource_check_input_values.go index c328b33..939d22a 100644 --- a/internal/service/cloudapi/disks/resource_check_input_values.go +++ b/internal/service/cloudapi/disks/resource_check_input_values.go @@ -2,76 +2,35 @@ package disks import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + req := account.ListRequest{} - urlValues := &url.Values{} - - accountList := []struct { - ID int `json:"id"` - }{} - - accountListAPI := "/restmachine/cloudapi/account/list" - - accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(accountListRaw), &accountList) + accountList, err := c.CloudAPI().Account().List(ctx, req) if err != nil { return false, err } - haveAccount := false - - myAccount := d.Get("account_id").(int) - for _, account := range accountList { - if account.ID == myAccount { - haveAccount = true - break - } - } - return haveAccount, nil + return len(accountList.FilterByID(accountId)) != 0, nil } func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) + req := locations.ListRequest{} - urlValues := &url.Values{} - - locationList := []struct { - GID int `json:"gid"` - }{} - - locationsListAPI := "/restmachine/cloudapi/locations/list" - - locationListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues) + locationList, err := c.CloudAPI().Locations().List(ctx, req) if err != nil { return false, err } - err = json.Unmarshal([]byte(locationListRaw), &locationList) - if err != nil { - return false, err - } - - haveGID := false - - gid := d.Get("gid").(int) - for _, location := range locationList { - if location.GID == gid { - haveGID = true - break - } - } - - return haveGID, nil + return len(locationList.FilterByGID(gid)) != 0, nil } diff --git a/internal/service/cloudapi/disks/resource_disk.go b/internal/service/cloudapi/disks/resource_disk.go index 98938b9..8545553 100644 --- a/internal/service/cloudapi/disks/resource_disk.go +++ b/internal/service/cloudapi/disks/resource_disk.go @@ -35,11 +35,11 @@ package disks import ( "context" "fmt" - "net/url" "strconv" "strings" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" @@ -52,7 +52,7 @@ import ( func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := disks.CreateRequest{} haveAccount, err := existAccountID(ctx, d, m) if err != nil { @@ -70,83 +70,78 @@ func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface return diag.Errorf("resourceDiskCreate: can't create Disk because GID %d is not allowed or does not exist", d.Get("gid").(int)) } - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int))) - urlValues.Add("name", d.Get("disk_name").(string)) - urlValues.Add("size", strconv.Itoa(d.Get("size_max").(int))) + req.AccountID = uint64(d.Get("account_id").(int)) + req.GID = uint64(d.Get("gid").(int)) + req.Name = d.Get("disk_name").(string) + req.Size = uint64(d.Get("size_max").(int)) if typeRaw, ok := d.GetOk("type"); ok { - urlValues.Add("type", strings.ToUpper(typeRaw.(string))) + req.Type = strings.ToUpper(typeRaw.(string)) } else { - urlValues.Add("type", "D") + req.Type = "D" } if sepId, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sep_id", strconv.Itoa(sepId.(int))) + req.SEPID = uint64(sepId.(int)) } if poolName, ok := d.GetOk("pool"); ok { - urlValues.Add("pool", poolName.(string)) + req.Pool = poolName.(string) } argVal, argSet := d.GetOk("desc") if argSet { - urlValues.Add("description", argVal.(string)) + req.Description = argVal.(string) } - diskId, err := c.DecortAPICall(ctx, "POST", disksCreateAPI, urlValues) + diskId, err := c.CloudAPI().Disks().Create(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} - - d.SetId(diskId) + d.SetId(strconv.FormatUint(diskId, 10)) if iotuneRaw, ok := d.GetOk("iotune"); ok { iot := iotuneRaw.([]interface{})[0] iotune := iot.(map[string]interface{}) - urlValues.Add("diskId", diskId) - urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int))) - urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int))) - urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int))) - urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int))) - urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int))) - urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int))) - urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int))) - urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int))) - urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int))) - urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int))) - urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int))) - urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int))) - urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int))) - - _, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues) + req := disks.LimitIORequest{ + DiskID: diskId, + IOPS: uint64(iotune["total_iops_sec"].(int)), + ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)), + TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)), + TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)), + WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)), + } + + _, err := c.CloudAPI().Disks().LimitIO(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if shareable := d.Get("shareable"); shareable.(bool) == true { - urlValues.Add("diskId", diskId) - _, err := c.DecortAPICall(ctx, "POST", disksShareAPI, urlValues) + req := disks.ShareRequest{ + DiskID: diskId, + } + + _, err := c.CloudAPI().Disks().Share(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} - } - - dgn := resourceDiskRead(ctx, d, m) - if dgn != nil { - return dgn } - return nil + return resourceDiskRead(ctx, d, m) } func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - urlValues := &url.Values{} c := m.(*controller.ControllerCfg) warnings := dc.Warnings{} @@ -161,13 +156,21 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{} switch disk.Status { case status.Destroyed, status.Purged: d.Set("disk_id", 0) + d.SetId("") return resourceDiskCreate(ctx, d, m) case status.Deleted: hasChangeState = true - urlValues.Add("diskId", d.Id()) - urlValues.Add("reason", d.Get("reason").(string)) + req := disks.RestoreRequest{ + DiskID: disk.ID, + } - _, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues) + if reason, ok := d.GetOk("reason"); ok { + req.Reason = reason.(string) + } else { + req.Reason = "Terraform automatic restore" + } + + _, err := c.CloudAPI().Disks().Restore(ctx, req) if err != nil { warnings.Add(err) } @@ -188,7 +191,7 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{} } } - flattenDisk(d, *disk) + flattenDisk(d, disk) return warnings.Get() } @@ -196,7 +199,6 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{} func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { c := m.(*controller.ControllerCfg) warnings := dc.Warnings{} - urlValues := &url.Values{} haveAccount, err := existAccountID(ctx, d, m) if err != nil { @@ -224,13 +226,21 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface switch disk.Status { case status.Destroyed, status.Purged: d.Set("disk_id", 0) + d.SetId("") return resourceDiskCreate(ctx, d, m) case status.Deleted: hasChangeState = true - urlValues.Add("diskId", d.Id()) - urlValues.Add("reason", d.Get("reason").(string)) + req := disks.RestoreRequest{ + DiskID: disk.ID, + } - _, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues) + if reason, ok := d.GetOk("reason"); ok { + req.Reason = reason.(string) + } else { + req.Reason = "Terraform automatic restore" + } + + _, err := c.CloudAPI().Disks().Restore(ctx, req) if err != nil { warnings.Add(err) } @@ -256,68 +266,75 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface if oldSize.(int) < newSize.(int) { log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB", d.Id(), oldSize.(int), newSize.(int)) - urlValues.Add("diskId", d.Id()) - urlValues.Add("size", strconv.Itoa(newSize.(int))) - _, err := c.DecortAPICall(ctx, "POST", disksResizeAPI, urlValues) + req := disks.ResizeRequest{ + DiskID: disk.ID, + Size: uint64(newSize.(int)), + } + + _, err := c.CloudAPI().Disks().Resize(ctx, req) if err != nil { return diag.FromErr(err) } + d.Set("size_max", newSize) } else if oldSize.(int) > newSize.(int) { return diag.FromErr(fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id())) } - urlValues = &url.Values{} } if d.HasChange("disk_name") { - urlValues.Add("diskId", d.Id()) - urlValues.Add("name", d.Get("disk_name").(string)) - _, err := c.DecortAPICall(ctx, "POST", disksRenameAPI, urlValues) + req := disks.RenameRequest{ + DiskID: disk.ID, + Name: d.Get("disk_name").(string), + } + + _, err := c.CloudAPI().Disks().Rename(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("iotune") { iot := d.Get("iotune").([]interface{})[0] iotune := iot.(map[string]interface{}) - urlValues.Add("diskId", d.Id()) - urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int))) - urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int))) - urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int))) - urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int))) - urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int))) - urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int))) - urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int))) - urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int))) - urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int))) - urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int))) - urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int))) - urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int))) - urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int))) - - _, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues) + req := disks.LimitIORequest{ + DiskID: disk.ID, + IOPS: uint64(iotune["total_iops_sec"].(int)), + ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)), + ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)), + ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)), + ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)), + TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)), + TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)), + TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)), + TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)), + WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)), + WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)), + WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)), + WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)), + } + + _, err := c.CloudAPI().Disks().LimitIO(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("shareable") { oldShare, newShare := d.GetChange("shareable") - urlValues = &url.Values{} - urlValues.Add("diskId", d.Id()) if oldShare.(bool) == false && newShare.(bool) == true { - _, err := c.DecortAPICall(ctx, "POST", disksShareAPI, urlValues) + req := disks.ShareRequest{DiskID: disk.ID} + + _, err := c.CloudAPI().Disks().Share(ctx, req) if err != nil { return diag.FromErr(err) } } if oldShare.(bool) == true && newShare.(bool) == false { - _, err := c.DecortAPICall(ctx, "POST", disksUnshareAPI, urlValues) + req := disks.UnshareRequest{DiskID: disk.ID} + + _, err := c.CloudAPI().Disks().Unshare(ctx, req) if err != nil { return diag.FromErr(err) } @@ -336,17 +353,22 @@ func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface if disk.Status == status.Destroyed || disk.Status == status.Purged { return nil } - params := &url.Values{} - params.Add("diskId", d.Id()) - params.Add("detach", strconv.FormatBool(d.Get("detach").(bool))) - params.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) - params.Add("reason", d.Get("reason").(string)) + + req := disks.DeleteRequest{ + DiskID: disk.ID, + Detach: d.Get("detach").(bool), + Permanently: d.Get("permanently").(bool), + Reason: d.Get("reason").(string), + } c := m.(*controller.ControllerCfg) - _, err = c.DecortAPICall(ctx, "POST", disksDeleteAPI, params) + _, err = c.CloudAPI().Disks().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + + d.SetId("") + return nil } @@ -531,11 +553,11 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, Computed: true, }, - "boot_partition": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of disk partitions", - }, + // "boot_partition": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of disk partitions", + // }, "computes": { Type: schema.TypeList, Computed: true, @@ -572,16 +594,16 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { Computed: true, Description: "Name of the device", }, - "disk_path": { - Type: schema.TypeString, - Computed: true, - Description: "Disk path", - }, - "guid": { - Type: schema.TypeInt, - Computed: true, - Description: "Disk ID on the storage side", - }, + // "disk_path": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk path", + // }, + // "guid": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Disk ID on the storage side", + // }, "image_id": { Type: schema.TypeInt, Computed: true, @@ -595,22 +617,21 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { }, Description: "IDs of images using the disk", }, - "iqn": { - Type: schema.TypeString, - Computed: true, - Description: "Disk IQN", - }, - "login": { - Type: schema.TypeString, - Computed: true, - Description: "Login to access the disk", - }, - "milestones": { - Type: schema.TypeInt, - Computed: true, - Description: "Milestones", - }, - + // "iqn": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Disk IQN", + // }, + // "login": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Login to access the disk", + // }, + // "milestones": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Milestones", + // }, "order": { Type: schema.TypeInt, Computed: true, @@ -626,36 +647,36 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { Computed: true, Description: "ID of the parent disk", }, - "passwd": { - Type: schema.TypeString, - Computed: true, - Description: "Password to access the disk", - }, + // "passwd": { + // Type: schema.TypeString, + // Computed: true, + // Description: "Password to access the disk", + // }, "pci_slot": { Type: schema.TypeInt, Computed: true, Description: "ID of the pci slot to which the disk is connected", }, - "purge_attempts": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of deletion attempts", - }, + // "purge_attempts": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Number of deletion attempts", + // }, "purge_time": { Type: schema.TypeInt, Computed: true, Description: "Time of the last deletion attempt", }, - "reality_device_number": { - Type: schema.TypeInt, - Computed: true, - Description: "Reality device number", - }, - "reference_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the reference to the disk", - }, + // "reality_device_number": { + // Type: schema.TypeInt, + // Computed: true, + // Description: "Reality device number", + // }, + // "reference_id": { + // Type: schema.TypeString, + // Computed: true, + // Description: "ID of the reference to the disk", + // }, "res_id": { Type: schema.TypeString, Computed: true, diff --git a/internal/service/cloudapi/disks/resource_disk_snapshot.go b/internal/service/cloudapi/disks/resource_disk_snapshot.go index 54a5357..4e30066 100644 --- a/internal/service/cloudapi/disks/resource_disk_snapshot.go +++ b/internal/service/cloudapi/disks/resource_disk_snapshot.go @@ -34,18 +34,16 @@ package disks import ( "context" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func resourceDiskSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - urlValues := &url.Values{} c := m.(*controller.ControllerCfg) disk, err := utilityDiskCheckPresence(ctx, d, m) @@ -54,7 +52,7 @@ func resourceDiskSnapshotCreate(ctx context.Context, d *schema.ResourceData, m i } snapshots := disk.Snapshots - snapshot := Snapshot{} + snapshot := disks.ItemSnapshot{} label := d.Get("label").(string) for _, sn := range snapshots { if label == sn.Label { @@ -65,30 +63,31 @@ func resourceDiskSnapshotCreate(ctx context.Context, d *schema.ResourceData, m i if label != snapshot.Label { return diag.Errorf("Snapshot with label \"%v\" not found", label) } + if rollback := d.Get("rollback").(bool); rollback { - urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int))) - urlValues.Add("label", label) - urlValues.Add("timestamp", strconv.Itoa(d.Get("timestamp").(int))) + req := disks.SnapshotRollbackRequest{ + DiskID: disk.ID, + Label: label, + TimeStamp: uint64(d.Get("timestamp").(int)), + } + log.Debugf("resourceDiskCreate: Snapshot rollback with label", label) - _, err := c.DecortAPICall(ctx, "POST", disksSnapshotRollbackAPI, urlValues) + _, err := c.CloudAPI().Disks().SnapshotRollback(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } return resourceDiskSnapshotRead(ctx, d, m) } func resourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { disk, err := utilityDiskCheckPresence(ctx, d, m) - if disk == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } + snapshots := disk.Snapshots - snapshot := Snapshot{} + snapshot := disks.ItemSnapshot{} label := d.Get("label").(string) for _, sn := range snapshots { if label == sn.Label { @@ -100,27 +99,20 @@ func resourceDiskSnapshotRead(ctx context.Context, d *schema.ResourceData, m int return diag.Errorf("Snapshot with label \"%v\" not found", label) } - d.SetId(d.Get("label").(string)) - d.Set("timestamp", snapshot.TimeStamp) - d.Set("guid", snapshot.Guid) - d.Set("res_id", snapshot.ResId) - d.Set("snap_set_guid", snapshot.SnapSetGuid) - d.Set("snap_set_time", snapshot.SnapSetTime) + flattenDiskSnapshot(d, snapshot) + return nil } func resourceDiskSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - urlValues := &url.Values{} c := m.(*controller.ControllerCfg) disk, err := utilityDiskCheckPresence(ctx, d, m) - if disk == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } + snapshots := disk.Snapshots - snapshot := Snapshot{} + snapshot := disks.ItemSnapshot{} label := d.Get("label").(string) for _, sn := range snapshots { if label == sn.Label { @@ -128,19 +120,23 @@ func resourceDiskSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m i break } } + if label != snapshot.Label { return diag.Errorf("Snapshot with label \"%v\" not found", label) } + if d.HasChange("rollback") && d.Get("rollback").(bool) == true { - urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int))) - urlValues.Add("label", label) - urlValues.Add("timestamp", strconv.Itoa(d.Get("timestamp").(int))) + req := disks.SnapshotRollbackRequest{ + DiskID: disk.ID, + Label: label, + TimeStamp: uint64(d.Get("timestamp").(int)), + } + log.Debugf("resourceDiskUpdtae: Snapshot rollback with label", label) - _, err := c.DecortAPICall(ctx, "POST", disksSnapshotRollbackAPI, urlValues) + _, err := c.CloudAPI().Disks().SnapshotRollback(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } return resourceDiskSnapshotRead(ctx, d, m) @@ -150,22 +146,23 @@ func resourceDiskSnapshotDelete(ctx context.Context, d *schema.ResourceData, m i c := m.(*controller.ControllerCfg) disk, err := utilityDiskCheckPresence(ctx, d, m) - if disk == nil { //if disk not exits, can't call snapshotDelete + if err != nil { d.SetId("") - if err != nil { - return diag.FromErr(err) - } - return nil + return diag.FromErr(err) } - params := &url.Values{} - params.Add("diskId", strconv.Itoa(d.Get("disk_id").(int))) - params.Add("label", d.Get("label").(string)) + req := disks.SnapshotDeleteRequest{ + DiskID: disk.ID, + Label: d.Get("label").(string), + } - _, err = c.DecortAPICall(ctx, "POST", disksSnapshotDeleteAPI, params) + _, err = c.CloudAPI().Disks().SnapshotDelete(ctx, req) if err != nil { return diag.FromErr(err) } + + d.SetId("") + return nil } diff --git a/internal/service/cloudapi/disks/utility_disk.go b/internal/service/cloudapi/disks/utility_disk.go index fd3e063..e28b752 100644 --- a/internal/service/cloudapi/disks/utility_disk.go +++ b/internal/service/cloudapi/disks/utility_disk.go @@ -34,39 +34,33 @@ package disks import ( "context" - "encoding/json" - "net/url" "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Disk, error) { +func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.RecordDisk, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - disk := &Disk{} + req := disks.GetRequest{} if d.Get("disk_id") != nil { if d.Get("disk_id").(int) == 0 { - urlValues.Add("diskId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = id } else { - urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int))) + req.DiskID = uint64(d.Get("disk_id").(int)) } } else { - urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int))) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = id } log.Debugf("utilityDiskCheckPresence: load disk") - diskRaw, err := c.DecortAPICall(ctx, "POST", disksGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(diskRaw), disk) + disk, err := c.CloudAPI().Disks().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/disks/utility_disk_list.go b/internal/service/cloudapi/disks/utility_disk_list.go index 630a4f5..df7a9fc 100644 --- a/internal/service/cloudapi/disks/utility_disk_list.go +++ b/internal/service/cloudapi/disks/utility_disk_list.go @@ -34,42 +34,34 @@ package disks import ( "context" - "encoding/json" - "net/url" - "strconv" "strings" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}, api string) (DisksList, error) { - diskList := DisksList{} +func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (disks.ListDisks, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := disks.ListRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } if diskType, ok := d.GetOk("type"); ok { - urlValues.Add("type", strings.ToUpper(diskType.(string))) + req.Type = strings.ToUpper(diskType.(string)) } if accountId, ok := d.GetOk("accountId"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } log.Debugf("utilityDiskListCheckPresence: load disk list") - diskListRaw, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(diskListRaw), &diskList) + diskList, err := c.CloudAPI().Disks().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/disks/utility_disk_list_unattached.go b/internal/service/cloudapi/disks/utility_disk_list_unattached.go new file mode 100644 index 0000000..c856a0b --- /dev/null +++ b/internal/service/cloudapi/disks/utility_disk_list_unattached.go @@ -0,0 +1,26 @@ +package disks + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" +) + +func utilityDiskListUnattachedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (disks.ListDisksUnattached, error) { + c := m.(*controller.ControllerCfg) + req := disks.ListUnattachedRequest{} + if accountId, ok := d.GetOk("accountId"); ok { + req.AccountID = uint64(accountId.(int)) + } + + log.Debugf("utilityDiskListUnattachedCheckPresence: load disk Unattached list") + unattachedList, err := c.CloudAPI().Disks().ListUnattached(ctx, req) + if err != nil { + return nil, err + } + + return unattachedList, nil +} diff --git a/internal/service/cloudapi/disks/utility_disk_types_detailed_list.go b/internal/service/cloudapi/disks/utility_disk_types_detailed_list.go index c92ffcf..ade8e21 100644 --- a/internal/service/cloudapi/disks/utility_disk_types_detailed_list.go +++ b/internal/service/cloudapi/disks/utility_disk_types_detailed_list.go @@ -34,26 +34,21 @@ package disks import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityDiskListTypesDetailedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (TypesDetailedList, error) { - listTypesDetailed := TypesDetailedList{} +func utilityDiskListTypesDetailedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]interface{}, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("detailed", "true") - log.Debugf("utilityDiskListTypesDetailedCheckPresence: load disk list Types Detailed") - diskListRaw, err := c.DecortAPICall(ctx, "POST", disksListTypesAPI, urlValues) - if err != nil { - return nil, err + req := disks.ListTypesRequest{ + Detailed: true, } - err = json.Unmarshal([]byte(diskListRaw), &listTypesDetailed) + log.Debugf("utilityDiskListTypesDetailedCheckPresence: load disk list Types Detailed") + listTypesDetailed, err := c.CloudAPI().Disks().ListTypes(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/disks/utility_disk_types_list.go b/internal/service/cloudapi/disks/utility_disk_types_list.go index 1c2a8c6..05cbb47 100644 --- a/internal/service/cloudapi/disks/utility_disk_types_list.go +++ b/internal/service/cloudapi/disks/utility_disk_types_list.go @@ -34,26 +34,21 @@ package disks import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityDiskListTypesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (TypesList, error) { - typesList := TypesList{} +func utilityDiskListTypesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]interface{}, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("detailed", "false") - log.Debugf("utilityDiskListTypesCheckPresence: load disk list Types Detailed") - diskListRaw, err := c.DecortAPICall(ctx, "POST", disksListTypesAPI, urlValues) - if err != nil { - return nil, err + req := disks.ListTypesRequest{ + Detailed: false, } - err = json.Unmarshal([]byte(diskListRaw), &typesList) + log.Debugf("utilityDiskListTypesCheckPresence: load disk list Types Detailed") + typesList, err := c.CloudAPI().Disks().ListTypes(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/extnet/api.go b/internal/service/cloudapi/extnet/api.go deleted file mode 100644 index 32e8d01..0000000 --- a/internal/service/cloudapi/extnet/api.go +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package extnet - -const extnetListAPI = "/restmachine/cloudapi/extnet/list" -const extnetListComputesAPI = "/restmachine/cloudapi/extnet/listComputes" -const extnetGetDefaultAPI = "/restmachine/cloudapi/extnet/getDefault" -const extnetGetAPI = "/restmachine/cloudapi/extnet/get" diff --git a/internal/service/cloudapi/extnet/data_source_extnet.go b/internal/service/cloudapi/extnet/data_source_extnet.go index 75a919f..2a5565c 100644 --- a/internal/service/cloudapi/extnet/data_source_extnet.go +++ b/internal/service/cloudapi/extnet/data_source_extnet.go @@ -34,12 +34,11 @@ package extnet import ( "context" + "strconv" - "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) func dataSourceExtnetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -48,75 +47,10 @@ func dataSourceExtnetRead(ctx context.Context, d *schema.ResourceData, m interfa return diag.FromErr(err) } - id := uuid.New() - d.SetId(id.String()) - d.Set("ckey", e.CKey) - d.Set("meta", flattens.FlattenMeta(e.Meta)) - d.Set("check__ips", e.CheckIPs) - d.Set("check_ips", e.CheckIps) - d.Set("default", e.Default) - d.Set("default_qos", flattenExtnetDefaultQos(e.DefaultQos)) - d.Set("desc", e.Desc) - d.Set("dns", e.Dns) - d.Set("excluded", e.Excluded) - d.Set("free_ips", e.FreeIps) - d.Set("gateway", e.Gateway) - d.Set("gid", e.GID) - d.Set("guid", e.GUID) - d.Set("ipcidr", e.IPCidr) - d.Set("milestones", e.Milestones) - d.Set("net_name", e.Name) - d.Set("network", e.Network) - d.Set("network_id", e.NetworkId) - d.Set("pre_reservations_num", e.PreReservationsNum) - d.Set("prefix", e.Prefix) - d.Set("pri_vnf_dev_id", e.PriVnfDevId) - d.Set("reservations", flattenExtnetReservations(e.Reservations)) - d.Set("shared_with", e.SharedWith) - d.Set("status", e.Status) - d.Set("vlan_id", e.VlanID) - d.Set("vnfs", flattenExtnetVNFS(e.VNFS)) - return nil -} - -func flattenExtnetReservations(ers ExtnetReservations) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, er := range ers { - temp := map[string]interface{}{ - "client_type": er.ClientType, - "domainname": er.DomainName, - "hostname": er.HostName, - "desc": er.Desc, - "ip": er.IP, - "mac": er.MAC, - "type": er.Type, - "vm_id": er.VMID, - } - res = append(res, temp) - } - - return res -} - -func flattenExtnetDefaultQos(edqos ExtnetQos) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "e_rate": edqos.ERate, - "guid": edqos.GUID, - "in_burst": edqos.InBurst, - "in_rate": edqos.InRate, - } - res = append(res, temp) - return res -} + d.SetId(strconv.FormatUint(e.ID, 10)) + flattenExtnet(d, e) -func flattenExtnetVNFS(evnfs ExtnetVNFS) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "dhcp": evnfs.DHCP, - } - res = append(res, temp) - return res + return nil } func dataSourceExtnetSchemaMake() map[string]*schema.Schema { @@ -164,6 +98,10 @@ func dataSourceExtnetSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, + "e_burst": { + Type: schema.TypeInt, + Computed: true, + }, "guid": { Type: schema.TypeString, Computed: true, @@ -193,8 +131,29 @@ func dataSourceExtnetSchemaMake() map[string]*schema.Schema { "excluded": { Type: schema.TypeList, Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_type": { + Type: schema.TypeString, + Computed: true, + }, + "mac": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vm_id": { + Type: schema.TypeInt, + Computed: true, + }, + }, }, }, "free_ips": { diff --git a/internal/service/cloudapi/extnet/data_source_extnet_computes_list.go b/internal/service/cloudapi/extnet/data_source_extnet_computes_list.go index d969845..76b0f98 100644 --- a/internal/service/cloudapi/extnet/data_source_extnet_computes_list.go +++ b/internal/service/cloudapi/extnet/data_source_extnet_computes_list.go @@ -41,37 +41,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenExtnetsComputes(ecs ExtnetExtendList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, ec := range ecs { - temp := map[string]interface{}{ - "net_id": ec.ID, - "ipaddr": ec.IPAddr, - "ipcidr": ec.IPCidr, - "name": ec.Name, - } - res = append(res, temp) - } - return res -} - -func flattenExtnetComputesList(ecl ExtnetComputesList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, ec := range ecl { - temp := map[string]interface{}{ - "account_id": ec.AccountId, - "account_name": ec.AccountName, - "extnets": flattenExtnetsComputes(ec.Extnets), - "id": ec.ID, - "name": ec.Name, - "rg_id": ec.RGID, - "rg_name": ec.RGName, - } - res = append(res, temp) - } - return res -} - func dataSourceExtnetComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { extnetComputesList, err := utilityExtnetComputesListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudapi/extnet/data_source_extnet_list.go b/internal/service/cloudapi/extnet/data_source_extnet_list.go index 94dcdbb..4a179d4 100644 --- a/internal/service/cloudapi/extnet/data_source_extnet_list.go +++ b/internal/service/cloudapi/extnet/data_source_extnet_list.go @@ -41,19 +41,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenExtnetList(el ExtnetList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, e := range el { - temp := map[string]interface{}{ - "net_id": e.ID, - "ipcidr": e.IPCidr, - "name": e.Name, - } - res = append(res, temp) - } - return res -} - func dataSourceExtnetListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { extnetList, err := utilityExtnetListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudapi/extnet/flattens.go b/internal/service/cloudapi/extnet/flattens.go new file mode 100644 index 0000000..ce5408a --- /dev/null +++ b/internal/service/cloudapi/extnet/flattens.go @@ -0,0 +1,137 @@ +package extnet + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenExtnet(d *schema.ResourceData, e *extnet.RecordExtNet) { + d.Set("ckey", e.CKey) + d.Set("meta", flattens.FlattenMeta(e.Meta)) + d.Set("check__ips", e.CheckIPs) + d.Set("check_ips", e.CheckIps) + d.Set("default", e.Default) + d.Set("default_qos", flattenExtnetDefaultQos(e.DefaultQOS)) + d.Set("desc", e.Description) + d.Set("dns", e.DNS) + d.Set("excluded", flattenExcluded(e.Excluded)) + d.Set("free_ips", e.FreeIPs) + d.Set("gateway", e.Gateway) + d.Set("gid", e.GID) + d.Set("guid", e.GUID) + d.Set("ipcidr", e.IPCIDR) + d.Set("milestones", e.Milestones) + d.Set("net_name", e.Name) + d.Set("network", e.Network) + d.Set("network_id", e.NetworkID) + d.Set("pre_reservations_num", e.PreReservationsNum) + d.Set("prefix", e.Prefix) + d.Set("pri_vnf_dev_id", e.PriVNFDevID) + d.Set("reservations", flattenExtnetReservations(e.Reservations)) + d.Set("shared_with", e.SharedWith) + d.Set("status", e.Status) + d.Set("vlan_id", e.VLANID) + d.Set("vnfs", flattenExtnetVNFS(e.VNFs)) +} + +func flattenExcluded(ex []extnet.Excluded) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range ex { + temp := map[string]interface{}{ + "client_type": item.ClientType, + "mac": item.MAC, + "ip": item.IP, + "type": item.Type, + "vm_id": item.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenExtnetReservations(ers extnet.ListReservations) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, er := range ers { + temp := map[string]interface{}{ + "client_type": er.ClientType, + "domainname": er.DomainName, + "hostname": er.Hostname, + "desc": er.Description, + "ip": er.IP, + "mac": er.MAC, + "type": er.Type, + "vm_id": er.VMID, + } + res = append(res, temp) + } + + return res +} + +func flattenExtnetDefaultQos(edqos extnet.QOS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "e_rate": edqos.ERate, + "e_burst": edqos.EBurst, + "guid": edqos.GUID, + "in_burst": edqos.InBurst, + "in_rate": edqos.InRate, + } + res = append(res, temp) + return res +} + +func flattenExtnetVNFS(evnfs extnet.VNFs) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "dhcp": evnfs.DHCP, + } + res = append(res, temp) + return res +} + +func flattenExtnetsComputes(ecs extnet.ListExtNetExtends) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, ec := range ecs { + temp := map[string]interface{}{ + "net_id": ec.ID, + "ipaddr": ec.IPAddr, + "ipcidr": ec.IPCIDR, + "name": ec.Name, + } + res = append(res, temp) + } + return res +} + +func flattenExtnetComputesList(ecl extnet.ListExtNetComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, ec := range ecl { + temp := map[string]interface{}{ + "account_id": ec.AccountID, + "account_name": ec.AccountName, + "extnets": flattenExtnetsComputes(ec.ExtNets), + "id": ec.ID, + "name": ec.Name, + "rg_id": ec.RGID, + "rg_name": ec.RGName, + } + res = append(res, temp) + } + return res +} + +func flattenExtnetList(el extnet.ListExtNets) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, e := range el { + temp := map[string]interface{}{ + "net_id": e.ID, + "ipcidr": e.IPCIDR, + "name": e.Name, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/extnet/models.go b/internal/service/cloudapi/extnet/models.go deleted file mode 100644 index e2d05c6..0000000 --- a/internal/service/cloudapi/extnet/models.go +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package extnet - -type Extnet struct { - ID int `json:"id"` - IPCidr string `json:"ipcidr"` - Name string `json:"name"` -} -type ExtnetExtend struct { - Extnet - IPAddr string `json:"ipaddr"` -} - -type ExtnetList []Extnet -type ExtnetExtendList []ExtnetExtend - -type ExtnetComputes struct { - AccountId int `json:"accountId"` - AccountName string `json:"accountName"` - Extnets ExtnetExtendList `json:"extnets"` - ID int `json:"id"` - Name string `json:"name"` - RGID int `json:"rgId"` - RGName string `json:"rgName"` -} - -type ExtnetComputesList []ExtnetComputes - -type ExtnetQos struct { - ERate int `json:"eRate"` - GUID string `json:"guid"` - InBurst int `json:"inBurst"` - InRate int `json:"inRate"` -} - -type ExtnetReservation struct { - ClientType string `json:"clientType"` - Desc string `json:"desc"` - DomainName string `json:"domainname"` - HostName string `json:"hostname"` - IP string `json:"ip"` - MAC string `json:"mac"` - Type string `json:"type"` - VMID int `json:"vmId"` -} - -type ExtnetReservations []ExtnetReservation - -type ExtnetVNFS struct { - DHCP int `json:"dhcp"` -} - -type ExtnetDetailed struct { - CKey string `json:"_ckey"` - Meta []interface{} `json:"_meta"` - CheckIPs []string `json:"checkIPs"` - CheckIps []string `json:"checkIps"` - Default bool `json:"default"` - DefaultQos ExtnetQos `json:"defaultQos"` - Desc string `json:"desc"` - Dns []string `json:"dns"` - Excluded []string `json:"excluded"` - FreeIps int `json:"free_ips"` - Gateway string `json:"gateway"` - GID int `json:"gid"` - GUID int `json:"guid"` - ID int `json:"id"` - IPCidr string `json:"ipcidr"` - Milestones int `json:"milestones"` - Name string `json:"name"` - Network string `json:"network"` - NetworkId int `json:"networkId"` - PreReservationsNum int `json:"preReservationsNum"` - Prefix int `json:"prefix"` - PriVnfDevId int `json:"priVnfDevId"` - Reservations ExtnetReservations `json:"reservations"` - SharedWith []int `json:"sharedWith"` - Status string `json:"status"` - VlanID int `json:"vlanId"` - VNFS ExtnetVNFS `json:"vnfs"` -} diff --git a/internal/service/cloudapi/extnet/utility_extnet.go b/internal/service/cloudapi/extnet/utility_extnet.go index 99a3e5d..d316174 100644 --- a/internal/service/cloudapi/extnet/utility_extnet.go +++ b/internal/service/cloudapi/extnet/utility_extnet.go @@ -34,30 +34,22 @@ package extnet import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityExtnetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*ExtnetDetailed, error) { - extnet := &ExtnetDetailed{} +func utilityExtnetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*extnet.RecordExtNet, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("net_id", strconv.Itoa(d.Get("net_id").(int))) - - log.Debugf("utilityExtnetCheckPresence") - extnetRaw, err := c.DecortAPICall(ctx, "POST", extnetGetAPI, urlValues) - if err != nil { - return nil, err + req := extnet.GetRequest{ + NetID: uint64(d.Get("net_id").(int)), } - err = json.Unmarshal([]byte(extnetRaw), &extnet) + log.Debugf("utilityExtnetCheckPresence") + extnet, err := c.CloudAPI().ExtNet().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/extnet/utility_extnet_computes_list.go b/internal/service/cloudapi/extnet/utility_extnet_computes_list.go index 05bc48a..c00654a 100644 --- a/internal/service/cloudapi/extnet/utility_extnet_computes_list.go +++ b/internal/service/cloudapi/extnet/utility_extnet_computes_list.go @@ -34,30 +34,22 @@ package extnet import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityExtnetComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ExtnetComputesList, error) { - extnetComputesList := ExtnetComputesList{} +func utilityExtnetComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (extnet.ListExtNetComputes, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - log.Debugf("utilityExtnetComputesListCheckPresence") - extnetComputesListRaw, err := c.DecortAPICall(ctx, "POST", extnetListComputesAPI, urlValues) - if err != nil { - return nil, err + req := extnet.ListComputesRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(extnetComputesListRaw), &extnetComputesList) + log.Debugf("utilityExtnetComputesListCheckPresence") + extnetComputesList, err := c.CloudAPI().ExtNet().ListComputes(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/extnet/utility_extnet_default.go b/internal/service/cloudapi/extnet/utility_extnet_default.go index f55f7b3..c8893eb 100644 --- a/internal/service/cloudapi/extnet/utility_extnet_default.go +++ b/internal/service/cloudapi/extnet/utility_extnet_default.go @@ -34,7 +34,7 @@ package extnet import ( "context" - "net/url" + "strconv" log "github.com/sirupsen/logrus" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" @@ -42,13 +42,12 @@ import ( func utilityExtnetDefaultCheckPresence(ctx context.Context, m interface{}) (string, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} log.Debugf("utilityExtnetDefaultCheckPresence") - res, err := c.DecortAPICall(ctx, "POST", extnetGetDefaultAPI, urlValues) + res, err := c.CloudAPI().ExtNet().GetDefault(ctx) if err != nil { return "", err } - return res, nil + return strconv.FormatUint(res, 10), nil } diff --git a/internal/service/cloudapi/extnet/utility_extnet_list.go b/internal/service/cloudapi/extnet/utility_extnet_list.go index dbd6d0f..92cb7cf 100644 --- a/internal/service/cloudapi/extnet/utility_extnet_list.go +++ b/internal/service/cloudapi/extnet/utility_extnet_list.go @@ -34,38 +34,30 @@ package extnet import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityExtnetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ExtnetList, error) { - extnetList := ExtnetList{} +func utilityExtnetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (extnet.ListExtNets, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := extnet.ListRequest{} if accountId, ok := d.GetOk("account_id"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityExtnetListCheckPresence") - extnetListRaw, err := c.DecortAPICall(ctx, "POST", extnetListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(extnetListRaw), &extnetList) + extnetList, err := c.CloudAPI().ExtNet().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/image/api.go b/internal/service/cloudapi/image/api.go deleted file mode 100644 index f662bfd..0000000 --- a/internal/service/cloudapi/image/api.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package image - -const imageCreateAPI = "/restmachine/cloudapi/image/create" -const imageCreateVirtualAPI = "/restmachine/cloudapi/image/createVirtual" -const imageGetAPI = "/restmachine/cloudapi/image/get" -const imageListGetAPI = "/restmachine/cloudapi/image/list" -const imageDeleteAPI = "/restmachine/cloudapi/image/delete" -const imageEditNameAPI = "/restmachine/cloudapi/image/rename" -const imageLinkAPI = "/restmachine/cloudapi/image/link" diff --git a/internal/service/cloudapi/image/data_source_image_list.go b/internal/service/cloudapi/image/data_source_image_list.go index 3793d53..79a500e 100644 --- a/internal/service/cloudapi/image/data_source_image_list.go +++ b/internal/service/cloudapi/image/data_source_image_list.go @@ -41,34 +41,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenImageList(il ImageList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, img := range il { - temp := map[string]interface{}{ - "account_id": img.AccountId, - "architecture": img.Architecture, - "boot_type": img.BootType, - "bootable": img.Bootable, - "cdrom": img.CDROM, - "desc": img.Description, - "drivers": img.Drivers, - "hot_resize": img.HotResize, - "image_id": img.Id, - "link_to": img.LinkTo, - "image_name": img.Name, - "pool_name": img.Pool, - "sep_id": img.SepId, - "size": img.Size, - "status": img.Status, - "type": img.Type, - "username": img.Username, - "virtual": img.Virtual, - } - res = append(res, temp) - } - return res -} - func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { imageList, err := utilityImageListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudapi/image/flattens.go b/internal/service/cloudapi/image/flattens.go index 1d6466c..a2393c7 100644 --- a/internal/service/cloudapi/image/flattens.go +++ b/internal/service/cloudapi/image/flattens.go @@ -1,13 +1,16 @@ package image -import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" +) -func flattenHistory(history []History) []map[string]interface{} { +func flattenHistory(history []image.History) []map[string]interface{} { temp := make([]map[string]interface{}, 0) for _, item := range history { t := map[string]interface{}{ - "id": item.Id, - "guid": item.Guid, + "id": item.ID, + "guid": item.GUID, "timestamp": item.Timestamp, } @@ -16,24 +19,24 @@ func flattenHistory(history []History) []map[string]interface{} { return temp } -func flattenImage(d *schema.ResourceData, img *ImageExtend) { +func flattenImage(d *schema.ResourceData, img *image.RecordImage) { d.Set("unc_path", img.UNCPath) d.Set("ckey", img.CKey) - d.Set("account_id", img.AccountId) - d.Set("acl", img.Acl) + d.Set("account_id", img.AccountID) + d.Set("acl", img.ACL) d.Set("architecture", img.Architecture) d.Set("boot_type", img.BootType) d.Set("bootable", img.Bootable) - d.Set("compute_ci_id", img.ComputeCiId) + d.Set("compute_ci_id", img.ComputeCIID) d.Set("deleted_time", img.DeletedTime) d.Set("desc", img.Description) d.Set("drivers", img.Drivers) d.Set("enabled", img.Enabled) - d.Set("gid", img.GridId) + d.Set("gid", img.GID) d.Set("guid", img.GUID) d.Set("history", flattenHistory(img.History)) d.Set("hot_resize", img.HotResize) - d.Set("image_id", img.Id) + d.Set("image_id", img.ID) d.Set("last_modified", img.LastModified) d.Set("link_to", img.LinkTo) d.Set("milestones", img.Milestones) @@ -43,9 +46,9 @@ func flattenImage(d *schema.ResourceData, img *ImageExtend) { d.Set("provider_name", img.ProviderName) d.Set("purge_attempts", img.PurgeAttempts) d.Set("present_to", img.PresentTo) - d.Set("res_id", img.ResId) + d.Set("res_id", img.ResID) d.Set("rescuecd", img.RescueCD) - d.Set("sep_id", img.SepId) + d.Set("sep_id", img.SepID) d.Set("shared_with", img.SharedWith) d.Set("size", img.Size) d.Set("status", img.Status) @@ -54,3 +57,31 @@ func flattenImage(d *schema.ResourceData, img *ImageExtend) { d.Set("username", img.Username) d.Set("version", img.Version) } + +func flattenImageList(il image.ListImages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, img := range il { + temp := map[string]interface{}{ + "account_id": img.AccountID, + "architecture": img.Architecture, + "boot_type": img.BootType, + "bootable": img.Bootable, + "cdrom": img.CDROM, + "desc": img.Description, + "drivers": img.Drivers, + "hot_resize": img.HotResize, + "image_id": img.ID, + "link_to": img.LinkTo, + "image_name": img.Name, + "pool_name": img.Pool, + "sep_id": img.SepID, + "size": img.Size, + "status": img.Status, + "type": img.Type, + "username": img.Username, + "virtual": img.Virtual, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/image/image_ds_subresource.go b/internal/service/cloudapi/image/image_ds_subresource.go index 9d9cd8d..c3323bd 100644 --- a/internal/service/cloudapi/image/image_ds_subresource.go +++ b/internal/service/cloudapi/image/image_ds_subresource.go @@ -79,7 +79,7 @@ func dataSourceImageExtendSchemaMake() map[string]*schema.Schema { Computed: true, }, "deleted_time": { - Type: schema.TypeString, + Type: schema.TypeInt, Computed: true, }, "desc": { diff --git a/internal/service/cloudapi/image/models.go b/internal/service/cloudapi/image/models.go deleted file mode 100644 index 12c2f94..0000000 --- a/internal/service/cloudapi/image/models.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package image - -/* -type History struct { - Guid string `json:"guid"` - Id int `json:"id"` - Timestamp int64 `json:"timestamp"` -} - -type Image struct { - ImageId int `json:"id"` - Name string `json:"name"` - Url string `json:"url"` - Gid int `json:"gid"` - Guid int `json:"guid"` - Boottype string `json:"bootType"` - Imagetype string `json:"type"` - Drivers []string `json:"drivers"` - Hotresize bool `json:"hotResize"` - Bootable bool `json:"bootable"` - Username string `json:"username"` - Password string `json:"password"` - AccountId int `json:"accountId"` - UsernameDL string `json:"usernameDL"` - PasswordDL string `json:"passwordDL"` - SepId int `json:"sepId"` - PoolName string `json:"pool"` - Architecture string `json:"architecture"` - UNCPath string `json:"UNCPath"` - LinkTo int `json:"linkTo"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Size int `json:"size"` - Version string `json:"version"` - Enabled bool `json:"enabled"` - ComputeciId int `json:"computeciId"` - Milestones int `json:"milestones"` - ProviderName string `json:"provider_name"` - PurgeAttempts int `json:"purgeAttempts"` - ReferenceId string `json:"referenceId"` - ResId string `json:"resId"` - ResName string `json:"resName"` - Rescuecd bool `json:"rescuecd"` - Meta []interface{} `json:"_meta"` - History []History `json:"history"` - LastModified int64 `json:"lastModified"` - Desc string `json:"desc"` - SharedWith []int `json:"sharedWith"` -} -*/ - -type Image struct { - AccountId int `json:"accountId"` - Architecture string `json:"architecture"` - BootType string `json:"bootType"` - Bootable bool `json:"bootable"` - CDROM bool `json:"cdrom"` - Description string `json:"desc"` - Drivers []string `json:"drivers"` - HotResize bool `json:"hotResize"` - Id int `json:"id"` - LinkTo int `json:"linkTo"` - Name string `json:"name"` - Pool string `json:"pool"` - SepId int `json:"sepId"` - Size int `json:"size"` - Status string `json:"status"` - Type string `json:"type"` - Username string `json:"username"` - Virtual bool `json:"virtual"` -} - -type ImageList []Image - -type History struct { - Guid string `json:"guid"` - Id int `json:"id"` - Timestamp int64 `json:"timestamp"` -} - -type ImageExtend struct { - UNCPath string `json:"UNCPath"` - CKey string `json:"_ckey"` - AccountId int `json:"accountId"` - Acl interface{} `json:"acl"` - Architecture string `json:"architecture"` - BootType string `json:"bootType"` - Bootable bool `json:"bootable"` - ComputeCiId int `json:"computeciId"` - DeletedTime int `json:"deletedTime"` - Description string `json:"desc"` - Drivers []string `json:"drivers"` - Enabled bool `json:"enabled"` - GridId int `json:"gid"` - GUID int `json:"guid"` - History []History `json:"history"` - HotResize bool `json:"hotResize"` - Id int `json:"id"` - LastModified int `json:"lastModified"` - LinkTo int `json:"linkTo"` - Milestones int `json:"milestones"` - Name string `json:"name"` - Password string `json:"password"` - Pool string `json:"pool"` - ProviderName string `json:"provider_name"` - PresentTo []int `json:"presentTo"` - PurgeAttempts int `json:"purgeAttempts"` - ResId string `json:"resId"` - RescueCD bool `json:"rescuecd"` - SepId int `json:"sepId"` - SharedWith []int `json:"sharedWith"` - Size int `json:"size"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` - Username string `json:"username"` - Version string `json:"version"` -} diff --git a/internal/service/cloudapi/image/resource_check_input_values.go b/internal/service/cloudapi/image/resource_check_input_values.go index c88c96a..d670d28 100644 --- a/internal/service/cloudapi/image/resource_check_input_values.go +++ b/internal/service/cloudapi/image/resource_check_input_values.go @@ -2,76 +2,35 @@ package image import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + req := account.ListRequest{} - urlValues := &url.Values{} - - accountList := []struct { - ID int `json:"id"` - }{} - - accountListAPI := "/restmachine/cloudapi/account/list" - - accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(accountListRaw), &accountList) + accounts, err := c.CloudAPI().Account().List(ctx, req) if err != nil { return false, err } - haveAccount := false - - myAccount := d.Get("account_id").(int) - for _, account := range accountList { - if account.ID == myAccount { - haveAccount = true - break - } - } - return haveAccount, nil + return len(accounts.FilterByID(accountId)) != 0, nil } func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) + req := locations.ListRequest{} - urlValues := &url.Values{} - - locationList := []struct { - GID int `json:"gid"` - }{} - - locationsListAPI := "/restmachine/cloudapi/locations/list" - - locationListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues) + locationList, err := c.CloudAPI().Locations().List(ctx, req) if err != nil { return false, err } - err = json.Unmarshal([]byte(locationListRaw), &locationList) - if err != nil { - return false, err - } - - haveGID := false - - gid := d.Get("gid").(int) - for _, location := range locationList { - if location.GID == gid { - haveGID = true - break - } - } - - return haveGID, nil + return len(locationList.FilterByGID(gid)) != 0, nil } diff --git a/internal/service/cloudapi/image/resource_image.go b/internal/service/cloudapi/image/resource_image.go index 7aa2aff..b161b24 100644 --- a/internal/service/cloudapi/image/resource_image.go +++ b/internal/service/cloudapi/image/resource_image.go @@ -34,13 +34,12 @@ package image import ( "context" - "encoding/json" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" @@ -70,68 +69,55 @@ func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interfac } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("url", d.Get("url").(string)) - urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int))) - urlValues.Add("boottype", d.Get("boot_type").(string)) - urlValues.Add("imagetype", d.Get("type").(string)) - - tstr := d.Get("drivers").([]interface{}) - temp := "" - l := len(tstr) - for i, str := range tstr { - s := "\"" + str.(string) + "\"" - if i != (l - 1) { - s += "," - } - temp = temp + s + req := image.CreateRequest{} + + req.Name = d.Get("name").(string) + req.URL = d.Get("url").(string) + req.GID = uint64(d.Get("gid").(int)) + req.BootType = d.Get("boot_type").(string) + req.ImageType = d.Get("type").(string) + + drivers := []string{} + for _, driver := range d.Get("drivers").([]interface{}) { + drivers = append(drivers, driver.(string)) } - temp = "[" + temp + "]" - urlValues.Add("drivers", temp) + + req.Drivers = drivers if hotresize, ok := d.GetOk("hot_resize"); ok { - urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool))) + req.HotResize = hotresize.(bool) } if username, ok := d.GetOk("username"); ok { - urlValues.Add("username", username.(string)) + req.Username = username.(string) } if password, ok := d.GetOk("password"); ok { - urlValues.Add("password", password.(string)) + req.Password = password.(string) } if accountId, ok := d.GetOk("account_id"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } if usernameDL, ok := d.GetOk("username_dl"); ok { - urlValues.Add("usernameDL", usernameDL.(string)) + req.UsernameDL = usernameDL.(string) } if passwordDL, ok := d.GetOk("password_dl"); ok { - urlValues.Add("passwordDL", passwordDL.(string)) + req.PasswordDL = passwordDL.(string) } if sepId, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sepId", strconv.Itoa(sepId.(int))) + req.SEPID = uint64(sepId.(int)) } if poolName, ok := d.GetOk("pool_name"); ok { - urlValues.Add("poolName", poolName.(string)) + req.Pool = poolName.(string) } if architecture, ok := d.GetOk("architecture"); ok { - urlValues.Add("architecture", architecture.(string)) - } - - res, err := c.DecortAPICall(ctx, "POST", imageCreateAPI, urlValues) - if err != nil { - return diag.FromErr(err) + req.Architecture = architecture.(string) } - i := make([]interface{}, 0) - err = json.Unmarshal([]byte(res), &i) + imageId, err := c.CloudAPI().Image().Create(ctx, req) if err != nil { return diag.FromErr(err) } - imageId := strconv.Itoa(int(i[1].(float64))) - // end innovation - d.SetId(imageId) + d.SetId(strconv.FormatUint(imageId, 10)) d.Set("image_id", imageId) _, err = utilityImageCheckPresence(ctx, d, m) @@ -139,12 +125,7 @@ func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interfac return diag.FromErr(err) } - diagnostics := resourceImageRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceImageRead(ctx, d, m) } func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -174,38 +155,39 @@ func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{ func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) - image, err := utilityImageCheckPresence(ctx, d, m) - if image == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } if permanently, ok := d.GetOk("permanently"); ok { - urlValues.Add("permanently", strconv.FormatBool(permanently.(bool))) + req.Permanently = permanently.(bool) } - _, err = c.DecortAPICall(ctx, "POST", imageDeleteAPI, urlValues) + _, err = c.CloudAPI().Image().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } -func resourceImageEditName(ctx context.Context, d *schema.ResourceData, m interface{}) error { +func resourceImageRename(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceImageEditName: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - urlValues.Add("name", d.Get("name").(string)) - _, err := c.DecortAPICall(ctx, "POST", imageEditNameAPI, urlValues) + req := image.RenameRequest{ + ImageID: uint64(d.Get("image_id").(int)), + Name: d.Get("name").(string), + } + + _, err := c.CloudAPI().Image().Rename(ctx, req) if err != nil { return err } @@ -214,7 +196,7 @@ func resourceImageEditName(ctx context.Context, d *schema.ResourceData, m interf } func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) + log.Debugf("resourceImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) haveGID, err := existGID(ctx, d, m) if err != nil { @@ -255,7 +237,7 @@ func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interfac } if d.HasChange("name") { - err := resourceImageEditName(ctx, d, m) + err := resourceImageRename(ctx, d, m) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudapi/image/resource_image_virtual.go b/internal/service/cloudapi/image/resource_image_virtual.go index 89662e3..e0b4018 100644 --- a/internal/service/cloudapi/image/resource_image_virtual.go +++ b/internal/service/cloudapi/image/resource_image_virtual.go @@ -34,30 +34,31 @@ package image import ( "context" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourceImageVirtualCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceImageVirtualCreate: called for image %s", d.Get("name").(string)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("targetId", strconv.Itoa(d.Get("target_id").(int))) + req := image.CreateVirtualRequest{ + Name: d.Get("name").(string), + TargetID: uint64(d.Get("target_id").(int)), + } - imageId, err := c.DecortAPICall(ctx, "POST", imageCreateVirtualAPI, urlValues) + imageId, err := c.CloudAPI().Image().CreateVirtual(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(imageId) + d.SetId(strconv.FormatUint(imageId, 10)) d.Set("image_id", imageId) _, err = utilityImageCheckPresence(ctx, d, m) @@ -65,19 +66,14 @@ func resourceImageVirtualCreate(ctx context.Context, d *schema.ResourceData, m i return diag.FromErr(err) } - diagnostics := resourceImageRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceImageRead(ctx, d, m) } -func resourceImageVirtualEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) +func resourceImageVirtualUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id()) if d.HasChange("name") { - err := resourceImageEditName(ctx, d, m) + err := resourceImageRename(ctx, d, m) if err != nil { return diag.FromErr(err) } @@ -96,10 +92,12 @@ func resourceImageVirtualEdit(ctx context.Context, d *schema.ResourceData, m int func resourceImageVirtualLink(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - urlValues.Add("targetId", strconv.Itoa(d.Get("link_to").(int))) - _, err := c.DecortAPICall(ctx, "POST", imageLinkAPI, urlValues) + req := image.LinkRequest{ + ImageID: uint64(d.Get("image_id").(int)), + TargetID: uint64(d.Get("link_to").(int)), + } + + _, err := c.CloudAPI().Image().Link(ctx, req) if err != nil { return err } @@ -113,7 +111,7 @@ func ResourceImageVirtual() *schema.Resource { CreateContext: resourceImageVirtualCreate, ReadContext: resourceImageRead, - UpdateContext: resourceImageVirtualEdit, + UpdateContext: resourceImageVirtualUpdate, DeleteContext: resourceImageDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudapi/image/utility_image.go b/internal/service/cloudapi/image/utility_image.go index 25a711b..5723d3e 100644 --- a/internal/service/cloudapi/image/utility_image.go +++ b/internal/service/cloudapi/image/utility_image.go @@ -34,43 +34,32 @@ package image import ( "context" - "encoding/json" - "errors" - "fmt" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*ImageExtend, error) { +func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := image.GetRequest{} if (strconv.Itoa(d.Get("image_id").(int))) != "0" { - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + req.ImageID = uint64(d.Get("image_id").(int)) } else { - urlValues.Add("imageId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ImageID = id } if showAll, ok := d.GetOk("show_all"); ok { - urlValues.Add("page", strconv.FormatBool(showAll.(bool))) + req.ShowAll = showAll.(bool) } - resp, err := c.DecortAPICall(ctx, "POST", imageGetAPI, urlValues) + image, err := c.CloudAPI().Image().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - - image := &ImageExtend{} - if err := json.Unmarshal([]byte(resp), image); err != nil { - return nil, errors.New(fmt.Sprint("Can not unmarshall data to image: ", resp, " ", image)) - } - return image, nil } diff --git a/internal/service/cloudapi/image/utility_image_list.go b/internal/service/cloudapi/image/utility_image_list.go index c89730f..aeebd2d 100644 --- a/internal/service/cloudapi/image/utility_image_list.go +++ b/internal/service/cloudapi/image/utility_image_list.go @@ -34,39 +34,31 @@ package image import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ImageList, error) { - imageList := ImageList{} +func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (image.ListImages, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := image.ListRequest{} if accountId, ok := d.GetOk("account_id"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityImageListCheckPresence: load image list") - imageListRaw, err := c.DecortAPICall(ctx, "POST", imageListGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(imageListRaw), &imageList) + imageList, err := c.CloudAPI().Image().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/k8s/api.go b/internal/service/cloudapi/k8s/api.go deleted file mode 100644 index 86400a6..0000000 --- a/internal/service/cloudapi/k8s/api.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package k8s - -const ( - K8sCreateAPI = "/restmachine/cloudapi/k8s/create" - K8sGetAPI = "/restmachine/cloudapi/k8s/get" - K8sUpdateAPI = "/restmachine/cloudapi/k8s/update" - K8sDeleteAPI = "/restmachine/cloudapi/k8s/delete" - K8sListAPI = "/restmachine/cloudapi/k8s/list" - K8sListDeletedAPI = "/restmachine/cloudapi/k8s/listDeleted" - K8sRestoreAPI = "/restmachine/cloudapi/k8s/restore" - K8sEnableAPI = "/restmachine/cloudapi/k8s/enable" - - K8sWgCreateAPI = "/restmachine/cloudapi/k8s/workersGroupAdd" - K8sWgDeleteAPI = "/restmachine/cloudapi/k8s/workersGroupDelete" - - K8sWorkerAddAPI = "/restmachine/cloudapi/k8s/workerAdd" - K8sWorkerDeleteAPI = "/restmachine/cloudapi/k8s/deleteWorkerFromGroup" - - K8sGetConfigAPI = "/restmachine/cloudapi/k8s/getConfig" - - LbGetAPI = "/restmachine/cloudapi/lb/get" - - AsyncTaskGetAPI = "/restmachine/cloudapi/tasks/get" -) diff --git a/internal/service/cloudapi/k8s/data_source_k8s.go b/internal/service/cloudapi/k8s/data_source_k8s.go index c4db28a..8d019fe 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s.go +++ b/internal/service/cloudapi/k8s/data_source_k8s.go @@ -34,52 +34,53 @@ package k8s import ( "context" - "encoding/json" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" - - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" ) func dataSourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - k8s, err := utilityDataK8sCheckPresence(ctx, d, m) + cluster, err := utilityDataK8sCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - d.SetId(strconv.FormatUint(k8s.ID, 10)) + d.SetId(strconv.FormatUint(cluster.ID, 10)) - k8sList, err := utilityK8sListCheckPresence(ctx, d, m, K8sListAPI) + k8sList, err := utilityK8sListCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } - curK8s := K8SItem{} + + curK8s := k8s.ItemK8SCluster{} for _, k8sCluster := range k8sList { - if k8sCluster.ID == k8s.ID { + if k8sCluster.ID == cluster.ID { curK8s = k8sCluster } } if curK8s.ID == 0 { - return diag.Errorf("Cluster with id %d not found in List clusters", k8s.ID) + return diag.Errorf("Cluster with id %d not found in List clusters", cluster.ID) } + d.Set("vins_id", curK8s.VINSID) - masterComputeList := make([]kvmvm.ComputeGetResp, 0, len(k8s.K8SGroups.Masters.DetailedInfo)) - workersComputeList := make([]kvmvm.ComputeGetResp, 0, len(k8s.K8SGroups.Workers)) - for _, masterNode := range k8s.K8SGroups.Masters.DetailedInfo { + masterComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + workersComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Workers)) + for _, masterNode := range cluster.K8SGroups.Masters.DetailedInfo { compute, err := utilityComputeCheckPresence(ctx, d, m, masterNode.ID) if err != nil { return diag.FromErr(err) } masterComputeList = append(masterComputeList, *compute) } - for _, worker := range k8s.K8SGroups.Workers { + for _, worker := range cluster.K8SGroups.Workers { for _, info := range worker.DetailedInfo { compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) if err != nil { @@ -90,29 +91,27 @@ func dataSourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{ } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues) + k8sId, _ := strconv.ParseUint(d.Id(), 10, 64) + + getConfigReq := k8s.GetConfigRequest{K8SID: k8sId} + + kubeconfig, err := c.CloudAPI().K8S().GetConfig(ctx, getConfigReq) if err != nil { log.Warnf("could not get kubeconfig: %v", err) } + d.Set("kubeconfig", kubeconfig) - urlValues = &url.Values{} - urlValues.Add("lbId", strconv.FormatUint(k8s.LBID, 10)) - resp, err := c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues) + getLbReq := lb.GetRequest{LBID: cluster.LBID} + lb, err := c.CloudAPI().LB().Get(ctx, getLbReq) if err != nil { return diag.FromErr(err) } - var lb LbRecord - if err := json.Unmarshal([]byte(resp), &lb); err != nil { - return diag.FromErr(err) - } d.Set("extnet_id", lb.ExtNetID) d.Set("lb_ip", lb.PrimaryNode.FrontendIP) - flattenK8sData(d, *k8s, masterComputeList, workersComputeList) + flattenK8sData(d, *cluster, masterComputeList, workersComputeList) return nil } diff --git a/internal/service/cloudapi/k8s/data_source_k8s_list.go b/internal/service/cloudapi/k8s/data_source_k8s_list.go index 3d86805..60dd22c 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s_list.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_list.go @@ -42,7 +42,7 @@ import ( ) func dataSourceK8sListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - k8sList, err := utilityK8sListCheckPresence(ctx, d, m, K8sListAPI) + k8sList, err := utilityK8sListCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) diff --git a/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go b/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go index c5d8ded..496aa76 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_list_deleted.go @@ -42,7 +42,7 @@ import ( ) func dataSourceK8sListDeletedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - k8sList, err := utilityK8sListCheckPresence(ctx, d, m, K8sListDeletedAPI) + k8sList, err := utilityK8sListDeletedCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) diff --git a/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go b/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go index 7cb3ccc..6025ac7 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_wg_list.go @@ -34,40 +34,14 @@ package k8s import ( "context" - "encoding/json" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" ) -func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (K8SGroupList, error) { - - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - - resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues) - if err != nil { - return nil, err - } - - if resp == "" { - return nil, nil - } - - var k8s K8SRecord - if err := json.Unmarshal([]byte(resp), &k8s); err != nil { - return nil, err - } - - return k8s.K8SGroups.Workers, nil -} - func dataSourceK8sWgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { wgList, err := utilityK8sWgListCheckPresence(ctx, d, m) if err != nil { @@ -76,9 +50,9 @@ func dataSourceK8sWgListRead(ctx context.Context, d *schema.ResourceData, m inte d.SetId(strconv.Itoa(d.Get("k8s_id").(int))) - workersComputeList := make(map[uint64][]kvmvm.ComputeGetResp) + workersComputeList := make(map[uint64][]compute.RecordCompute) for _, worker := range wgList { - workersComputeList[worker.ID] = make([]kvmvm.ComputeGetResp, 0, len(worker.DetailedInfo)) + workersComputeList[worker.ID] = make([]compute.RecordCompute, 0, len(worker.DetailedInfo)) for _, info := range worker.DetailedInfo { compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) if err != nil { diff --git a/internal/service/cloudapi/k8s/flattens.go b/internal/service/cloudapi/k8s/flattens.go index 3a8e02c..d2983c1 100644 --- a/internal/service/cloudapi/k8s/flattens.go +++ b/internal/service/cloudapi/k8s/flattens.go @@ -34,10 +34,11 @@ package k8s import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" ) -func flattenAclList(aclList ACLList) []map[string]interface{} { +func flattenAclList(aclList k8s.ListACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, acl := range aclList { temp := map[string]interface{}{ @@ -53,7 +54,7 @@ func flattenAclList(aclList ACLList) []map[string]interface{} { return res } -func flattenAcl(acl ACLGroup) []map[string]interface{} { +func flattenAcl(acl k8s.RecordACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "account_acl": flattenAclList(acl.AccountACL), @@ -65,11 +66,11 @@ func flattenAcl(acl ACLGroup) []map[string]interface{} { return res } -func flattenInterfaces(interfaces []kvmvm.InterfaceRecord) []map[string]interface{} { +func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, interfaceCompute := range interfaces { temp := map[string]interface{}{ - "def_gw": interfaceCompute.DefaultGW, + "def_gw": interfaceCompute.DefGW, "ip_address": interfaceCompute.IPAddress, } res = append(res, temp) @@ -78,7 +79,7 @@ func flattenInterfaces(interfaces []kvmvm.InterfaceRecord) []map[string]interfac return res } -func flattenDetailedInfo(detailedInfoList DetailedInfoList, computes []kvmvm.ComputeGetResp) []map[string]interface{} { +func flattenDetailedInfo(detailedInfoList k8s.ListDetailedInfo, computes []compute.RecordCompute) []map[string]interface{} { res := make([]map[string]interface{}, 0) if computes != nil { for i, detailedInfo := range detailedInfoList { @@ -88,8 +89,8 @@ func flattenDetailedInfo(detailedInfoList DetailedInfoList, computes []kvmvm.Com "status": detailedInfo.Status, "tech_status": detailedInfo.TechStatus, "interfaces": flattenInterfaces(computes[i].Interfaces), - "natable_vins_ip": computes[i].NatableVinsIP, - "natable_vins_network": computes[i].NatableVinsNet, + "natable_vins_ip": computes[i].NatableVINSIP, + "natable_vins_network": computes[i].NatableVINSNetwork, } res = append(res, temp) } @@ -108,7 +109,7 @@ func flattenDetailedInfo(detailedInfoList DetailedInfoList, computes []kvmvm.Com return res } -func flattenMasterGroup(mastersGroup MasterGroup, masters []kvmvm.ComputeGetResp) []map[string]interface{} { +func flattenMasterGroup(mastersGroup k8s.MasterGroup, masters []compute.RecordCompute) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cpu": mastersGroup.CPU, @@ -124,7 +125,7 @@ func flattenMasterGroup(mastersGroup MasterGroup, masters []kvmvm.ComputeGetResp return res } -func flattenK8sGroup(k8SGroupList K8SGroupList, workers []kvmvm.ComputeGetResp) []map[string]interface{} { +func flattenK8sGroup(k8SGroupList k8s.ListK8SGroups, workers []compute.RecordCompute) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, k8sGroup := range k8SGroupList { temp := map[string]interface{}{ @@ -146,7 +147,7 @@ func flattenK8sGroup(k8SGroupList K8SGroupList, workers []kvmvm.ComputeGetResp) return res } -func flattenK8sGroups(k8sGroups K8SGroups, masters []kvmvm.ComputeGetResp, workers []kvmvm.ComputeGetResp) []map[string]interface{} { +func flattenK8sGroups(k8sGroups k8s.RecordK8SGroups, masters []compute.RecordCompute, workers []compute.RecordCompute) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "masters": flattenMasterGroup(k8sGroups.Masters, masters), @@ -156,30 +157,30 @@ func flattenK8sGroups(k8sGroups K8SGroups, masters []kvmvm.ComputeGetResp, worke return res } -func flattenK8sData(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.ComputeGetResp, workers []kvmvm.ComputeGetResp) { - d.Set("acl", flattenAcl(k8s.ACL)) - d.Set("account_id", k8s.AccountID) - d.Set("account_name", k8s.AccountName) - d.Set("bservice_id", k8s.BServiceID) - d.Set("k8sci_id", k8s.CIID) - d.Set("created_by", k8s.CreatedBy) - d.Set("created_time", k8s.CreatedTime) - d.Set("deleted_by", k8s.DeletedBy) - d.Set("deleted_time", k8s.DeletedTime) - d.Set("k8s_ci_name", k8s.K8CIName) - d.Set("masters", flattenMasterGroup(k8s.K8SGroups.Masters, masters)) - d.Set("workers", flattenK8sGroup(k8s.K8SGroups.Workers, workers)) - d.Set("lb_id", k8s.LBID) - d.Set("name", k8s.Name) - d.Set("rg_id", k8s.RGID) - d.Set("rg_name", k8s.RGName) - d.Set("status", k8s.Status) - d.Set("tech_status", k8s.TechStatus) - d.Set("updated_by", k8s.UpdatedBy) - d.Set("updated_time", k8s.UpdatedTime) +func flattenK8sData(d *schema.ResourceData, cluster k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) { + d.Set("acl", flattenAcl(cluster.ACL)) + d.Set("account_id", cluster.AccountID) + d.Set("account_name", cluster.AccountName) + d.Set("bservice_id", cluster.BServiceID) + d.Set("k8sci_id", cluster.CIID) + d.Set("created_by", cluster.CreatedBy) + d.Set("created_time", cluster.CreatedTime) + d.Set("deleted_by", cluster.DeletedBy) + d.Set("deleted_time", cluster.DeletedTime) + d.Set("k8s_ci_name", cluster.K8CIName) + d.Set("masters", flattenMasterGroup(cluster.K8SGroups.Masters, masters)) + d.Set("workers", flattenK8sGroup(cluster.K8SGroups.Workers, workers)) + d.Set("lb_id", cluster.LBID) + d.Set("name", cluster.Name) + d.Set("rg_id", cluster.RGID) + d.Set("rg_name", cluster.RGName) + d.Set("status", cluster.Status) + d.Set("tech_status", cluster.TechStatus) + d.Set("updated_by", cluster.UpdatedBy) + d.Set("updated_time", cluster.UpdatedTime) } -func flattenServiceAccount(serviceAccount ServiceAccount) []map[string]interface{} { +func flattenServiceAccount(serviceAccount k8s.RecordServiceAccount) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "guid": serviceAccount.GUID, @@ -190,7 +191,7 @@ func flattenServiceAccount(serviceAccount ServiceAccount) []map[string]interface return res } -func flattenWorkersGroup(workersGroups K8SGroupList) []map[string]interface{} { +func flattenWorkersGroup(workersGroups k8s.ListK8SGroups) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, worker := range workersGroups { temp := map[string]interface{}{ @@ -211,11 +212,7 @@ func flattenWorkersGroup(workersGroups K8SGroupList) []map[string]interface{} { return res } -func flattenConfig(config interface{}) map[string]interface{} { - return config.(map[string]interface{}) -} - -func flattenK8sItems(k8sItems K8SList) []map[string]interface{} { +func flattenK8sItems(k8sItems k8s.ListK8SClusters) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, item := range k8sItems { temp := map[string]interface{}{ @@ -252,11 +249,11 @@ func flattenK8sItems(k8sItems K8SList) []map[string]interface{} { return res } -func flattenK8sList(d *schema.ResourceData, k8sItems K8SList) { +func flattenK8sList(d *schema.ResourceData, k8sItems k8s.ListK8SClusters) { d.Set("items", flattenK8sItems(k8sItems)) } -func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.ComputeGetResp, workers []kvmvm.ComputeGetResp) { +func flattenResourceK8s(d *schema.ResourceData, k8s k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) { wg_name := k8s.K8SGroups.Workers[0].Name d.Set("acl", flattenAcl(k8s.ACL)) @@ -282,9 +279,10 @@ func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.C d.Set("updated_by", k8s.UpdatedBy) d.Set("updated_time", k8s.UpdatedTime) d.Set("default_wg_id", k8s.K8SGroups.Workers[0].ID) + d.Set("network_plugin", k8s.NetworkPlugin) } -func flattenWg(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetResp) { +func flattenWg(d *schema.ResourceData, wg k8s.ItemK8SGroup, computes []compute.RecordCompute) { d.Set("annotations", wg.Annotations) d.Set("cpu", wg.CPU) d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes)) @@ -297,7 +295,7 @@ func flattenWg(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetR d.Set("taints", wg.Taints) } -func flattenWgList(wgList K8SGroupList, computesMap map[uint64][]kvmvm.ComputeGetResp) []map[string]interface{} { +func flattenWgList(wgList k8s.ListK8SGroups, computesMap map[uint64][]compute.RecordCompute) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, wg := range wgList { computes := computesMap[wg.ID] @@ -320,6 +318,6 @@ func flattenWgList(wgList K8SGroupList, computesMap map[uint64][]kvmvm.ComputeGe return res } -func flattenItemsWg(d *schema.ResourceData, wgList K8SGroupList, computes map[uint64][]kvmvm.ComputeGetResp) { +func flattenItemsWg(d *schema.ResourceData, wgList k8s.ListK8SGroups, computes map[uint64][]compute.RecordCompute) { d.Set("items", flattenWgList(wgList, computes)) } diff --git a/internal/service/cloudapi/k8s/node_subresource.go b/internal/service/cloudapi/k8s/node_subresource.go index a2c725f..ae4ad40 100644 --- a/internal/service/cloudapi/k8s/node_subresource.go +++ b/internal/service/cloudapi/k8s/node_subresource.go @@ -87,21 +87,18 @@ func nodeK8sSubresourceSchemaMake() map[string]*schema.Schema { "cpu": { Type: schema.TypeInt, Required: true, - ForceNew: true, Description: "Node CPU count.", }, "ram": { Type: schema.TypeInt, Required: true, - ForceNew: true, Description: "Node RAM in MB.", }, "disk": { Type: schema.TypeInt, Required: true, - ForceNew: true, Description: "Node boot disk size in GB.", }, } diff --git a/internal/service/cloudapi/k8s/resource_check_input_values.go b/internal/service/cloudapi/k8s/resource_check_input_values.go index 7dd3656..c00d090 100644 --- a/internal/service/cloudapi/k8s/resource_check_input_values.go +++ b/internal/service/cloudapi/k8s/resource_check_input_values.go @@ -2,142 +2,68 @@ package k8s import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8ci" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func existK8sID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + k8sID := uint64(d.Get("k8s_id").(int)) + req := k8s.ListRequest{} - k8sList := []struct { - ID int `json:"id"` - }{} - - k8sListAPI := "/restmachine/cloudapi/k8s/list" - - k8sListRaw, err := c.DecortAPICall(ctx, "POST", k8sListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(k8sListRaw), &k8sList) + k8sList, err := c.CloudAPI().K8S().List(ctx, req) if err != nil { return false, err } - haveK8s := false - k8sID := d.Get("k8s_id").(int) - for _, k8s := range k8sList { - if k8s.ID == k8sID { - haveK8s = true - break - } - } - - return haveK8s, nil + return len(k8sList.FilterByID(k8sID)) != 0, nil } func existK8sCIID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + k8sciID := uint64(d.Get("k8sci_id").(int)) + req := k8ci.ListRequest{} - k8sciList := []struct { - ID int `json:"id"` - }{} - - k8sciListAPI := "/restmachine/cloudapi/k8ci/list" - - k8sciListRaw, err := c.DecortAPICall(ctx, "POST", k8sciListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(k8sciListRaw), &k8sciList) + k8sciList, err := c.CloudAPI().K8CI().List(ctx, req) if err != nil { return false, err } - haveK8sCI := false - k8sciID := d.Get("k8sci_id").(int) - for _, k8ci := range k8sciList { - if k8ci.ID == k8sciID { - haveK8sCI = true - break - } - } - - return haveK8sCI, nil + return len(k8sciList.FilterByID(k8sciID)) != 0, nil } func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + rgID := uint64(d.Get("rg_id").(int)) + req := rg.ListRequest{} - rgList := []struct { - ID int `json:"id"` - }{} - - rgListAPI := "/restmachine/cloudapi/rg/list" - - rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(rgListRaw), &rgList) + rgList, err := c.CloudAPI().RG().List(ctx, req) if err != nil { return false, err } - haveRG := false - rgId := d.Get("rg_id").(int) - for _, rg := range rgList { - if rg.ID == rgId { - haveRG = true - break - } - } - - return haveRG, nil + return len(rgList.FilterByID(rgID)) != 0, nil } func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { - extNetID := d.Get("extnet_id").(int) + extNetID := uint64(d.Get("extnet_id").(int)) if extNetID == 0 { return true, nil } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := extnet.ListRequest{} - extNetList := []struct { - ID int `json:"id"` - }{} - - extNetListAPI := "/restmachine/cloudapi/extnet/list" - - extNetListRaw, err := c.DecortAPICall(ctx, "POST", extNetListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(extNetListRaw), &extNetList) + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) if err != nil { return false, err } - haveExtNet := false - for _, extNet := range extNetList { - if extNet.ID == extNetID { - haveExtNet = true - break - } - } - - return haveExtNet, nil + return len(extNetList.FilterByID(extNetID)) != 0, nil } diff --git a/internal/service/cloudapi/k8s/resource_k8s.go b/internal/service/cloudapi/k8s/resource_k8s.go index d4b1c5b..c3bb819 100644 --- a/internal/service/cloudapi/k8s/resource_k8s.go +++ b/internal/service/cloudapi/k8s/resource_k8s.go @@ -34,19 +34,21 @@ package k8s import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" ) @@ -83,11 +85,13 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{ } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - urlValues.Add("k8ciId", strconv.Itoa(d.Get("k8sci_id").(int))) - urlValues.Add("workerGroupName", d.Get("wg_name").(string)) + createReq := k8s.CreateRequest{} + + createReq.Name = d.Get("name").(string) + createReq.RGID = uint64(d.Get("rg_id").(int)) + createReq.K8SCIID = uint64(d.Get("k8sci_id").(int)) + createReq.WorkerGroupName = d.Get("wg_name").(string) + createReq.NetworkPlugin = d.Get("network_plugin").(string) var masterNode K8sNodeRecord if masters, ok := d.GetOk("masters"); ok { @@ -95,12 +99,12 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{ } else { masterNode = nodeMasterDefault() } - urlValues.Add("masterNum", strconv.Itoa(masterNode.Num)) - urlValues.Add("masterCpu", strconv.Itoa(masterNode.Cpu)) - urlValues.Add("masterRam", strconv.Itoa(masterNode.Ram)) - urlValues.Add("masterDisk", strconv.Itoa(masterNode.Disk)) - urlValues.Add("masterSepId", strconv.Itoa(masterNode.SepID)) - urlValues.Add("masterSepPool", masterNode.SepPool) + createReq.MasterNum = uint(masterNode.Num) + createReq.MasterCPU = uint(masterNode.Cpu) + createReq.MasterRAM = uint(masterNode.Ram) + createReq.MasterDisk = uint(masterNode.Disk) + createReq.MasterSEPID = uint64(masterNode.SepID) + createReq.MasterSEPPool = masterNode.SepPool var workerNode K8sNodeRecord if workers, ok := d.GetOk("workers"); ok { @@ -108,68 +112,66 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{ } else { workerNode = nodeWorkerDefault() } - urlValues.Add("workerNum", strconv.Itoa(workerNode.Num)) - urlValues.Add("workerCpu", strconv.Itoa(workerNode.Cpu)) - urlValues.Add("workerRam", strconv.Itoa(workerNode.Ram)) - urlValues.Add("workerDisk", strconv.Itoa(workerNode.Disk)) - urlValues.Add("workerSepId", strconv.Itoa(workerNode.SepID)) - urlValues.Add("workerSepPool", workerNode.SepPool) + + createReq.WorkerNum = uint(workerNode.Num) + createReq.WorkerCPU = uint(workerNode.Cpu) + createReq.WorkerRAM = uint(workerNode.Ram) + createReq.WorkerDisk = uint(workerNode.Disk) + createReq.WorkerSEPID = uint64(workerNode.SepID) + createReq.WorkerSEPPool = workerNode.SepPool if labels, ok := d.GetOk("labels"); ok { labels := labels.([]interface{}) for _, label := range labels { - urlValues.Add("labels", label.(string)) + createReq.Labels = append(createReq.Labels, label.(string)) } } if taints, ok := d.GetOk("taints"); ok { taints := taints.([]interface{}) for _, taint := range taints { - urlValues.Add("taints", taint.(string)) + createReq.Taints = append(createReq.Taints, taint.(string)) } } if annotations, ok := d.GetOk("annotations"); ok { annotations := annotations.([]interface{}) for _, annotation := range annotations { - urlValues.Add("annotations", annotation.(string)) + createReq.Annotations = append(createReq.Annotations, annotation.(string)) } } if withLB, ok := d.GetOk("with_lb"); ok { - urlValues.Add("withLB", strconv.FormatBool(withLB.(bool))) + createReq.WithLB = withLB.(bool) } else { - urlValues.Add("withLB", strconv.FormatBool(true)) + createReq.WithLB = true } if extNet, ok := d.GetOk("extnet_id"); ok { - urlValues.Add("extnetId", strconv.Itoa(extNet.(int))) + createReq.ExtNetID = uint64(extNet.(int)) } else { - urlValues.Add("extnetId", "0") + createReq.ExtNetID = 0 } if desc, ok := d.GetOk("desc"); ok { - urlValues.Add("desc", desc.(string)) + createReq.Description = desc.(string) } - resp, err := c.DecortAPICall(ctx, "POST", K8sCreateAPI, urlValues) + resp, err := c.CloudAPI().K8S().Create(ctx, createReq) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} - urlValues.Add("auditId", strings.Trim(resp, `"`)) + taskReq := tasks.GetRequest{ + AuditID: strings.Trim(resp, `"`), + } for { - resp, err := c.DecortAPICall(ctx, "POST", AsyncTaskGetAPI, urlValues) + task, err := c.CloudAPI().Tasks().Get(ctx, taskReq) if err != nil { return diag.FromErr(err) } - task := AsyncTask{} - if err := json.Unmarshal([]byte(resp), &task); err != nil { - return diag.FromErr(err) - } log.Debugf("resourceK8sCreate: instance creating - %s", task.Stage) if task.Completed { @@ -188,7 +190,7 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{ } func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - k8s, err := utilityK8sCheckPresence(ctx, d, m) + cluster, err := utilityK8sCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) @@ -198,29 +200,35 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) hasChanged := false - switch k8s.Status { + switch cluster.Status { case status.Modeled: - return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", k8s.Status) + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", cluster.Status) case status.Creating: case status.Created: case status.Deleting: case status.Deleted: - urlVal := &url.Values{} - urlVal.Add("k8sId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := k8s.RestoreRequest{ + K8SID: id, + } - _, err := c.DecortAPICall(ctx, "POST", K8sRestoreAPI, urlVal) + _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", K8sEnableAPI, urlVal) + enableReq := k8s.DisabelEnableRequest{ + K8SID: id, + } + + _, err = c.CloudAPI().K8S().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } hasChanged = true case status.Destroying: - return diag.Errorf("The k8s cluster is in progress with status: %s", k8s.Status) + return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) case status.Destroyed: d.SetId("") return resourceK8sCreate(ctx, d, m) @@ -228,13 +236,13 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) case status.Enabled: case status.Disabling: case status.Disabled: - log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", k8s.Status) + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", cluster.Status) case status.Restoring: } if hasChanged { - k8s, err = utilityK8sCheckPresence(ctx, d, m) - if k8s == nil { + cluster, err = utilityK8sCheckPresence(ctx, d, m) + if cluster == nil { d.SetId("") if err != nil { return diag.FromErr(err) @@ -243,32 +251,45 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) } } - k8sList, err := utilityK8sListCheckPresence(ctx, d, m, K8sListAPI) + if d.Get("start").(bool) { + if cluster.TechStatus == "STOPPED" { + req := k8s.StartRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } + + k8sList, err := utilityK8sListCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } - curK8s := K8SItem{} + curK8s := k8s.ItemK8SCluster{} for _, k8sCluster := range k8sList { - if k8sCluster.ID == k8s.ID { + if k8sCluster.ID == cluster.ID { curK8s = k8sCluster } } if curK8s.ID == 0 { - return diag.Errorf("Cluster with id %d not found", k8s.ID) + return diag.Errorf("Cluster with id %d not found", cluster.ID) } + d.Set("vins_id", curK8s.VINSID) - masterComputeList := make([]kvmvm.ComputeGetResp, 0, len(k8s.K8SGroups.Masters.DetailedInfo)) - workersComputeList := make([]kvmvm.ComputeGetResp, 0, len(k8s.K8SGroups.Workers)) - for _, masterNode := range k8s.K8SGroups.Masters.DetailedInfo { + masterComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Masters.DetailedInfo)) + workersComputeList := make([]compute.RecordCompute, 0, len(cluster.K8SGroups.Workers)) + for _, masterNode := range cluster.K8SGroups.Masters.DetailedInfo { compute, err := utilityComputeCheckPresence(ctx, d, m, masterNode.ID) if err != nil { return diag.FromErr(err) } masterComputeList = append(masterComputeList, *compute) } - for _, worker := range k8s.K8SGroups.Workers { + for _, worker := range cluster.K8SGroups.Workers { for _, info := range worker.DetailedInfo { compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) if err != nil { @@ -278,29 +299,29 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) } } - flattenResourceK8s(d, *k8s, masterComputeList, workersComputeList) + flattenResourceK8s(d, *cluster, masterComputeList, workersComputeList) - urlValues := &url.Values{} - urlValues.Add("lbId", strconv.FormatUint(k8s.LBID, 10)) + lbGetReq := lb.GetRequest{ + LBID: cluster.LBID, + } - resp, err := c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues) + lb, err := c.CloudAPI().LB().Get(ctx, lbGetReq) if err != nil { return diag.FromErr(err) } - var lb LbRecord - if err := json.Unmarshal([]byte(resp), &lb); err != nil { - return diag.FromErr(err) - } d.Set("extnet_id", lb.ExtNetID) d.Set("lb_ip", lb.PrimaryNode.FrontendIP) - urlValues = &url.Values{} - urlValues.Add("k8sId", d.Id()) - kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues) + kubeconfigReq := k8s.GetConfigRequest{ + K8SID: cluster.ID, + } + + kubeconfig, err := c.CloudAPI().K8S().GetConfig(ctx, kubeconfigReq) if err != nil { log.Warnf("could not get kubeconfig: %v", err) } + d.Set("kubeconfig", kubeconfig) return nil @@ -329,36 +350,42 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{ return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because K8sCIID %d is not allowed or does not exist", d.Get("k8sci_id").(int)) } - k8s, err := utilityK8sCheckPresence(ctx, d, m) + cluster, err := utilityK8sCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } hasChanged := false - switch k8s.Status { + switch cluster.Status { case status.Modeled: - return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", k8s.Status) + return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", cluster.Status) case status.Creating: case status.Created: case status.Deleting: case status.Deleted: - urlVal := &url.Values{} - urlVal.Add("k8sId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := k8s.RestoreRequest{ + K8SID: id, + } - _, err := c.DecortAPICall(ctx, "POST", K8sRestoreAPI, urlVal) + _, err := c.CloudAPI().K8S().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", K8sEnableAPI, urlVal) + enableReq := k8s.DisabelEnableRequest{ + K8SID: id, + } + + _, err = c.CloudAPI().K8S().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } hasChanged = true case status.Destroying: - return diag.Errorf("The k8s cluster is in progress with status: %s", k8s.Status) + return diag.Errorf("The k8s cluster is in progress with status: %s", cluster.Status) case status.Destroyed: d.SetId("") return resourceK8sCreate(ctx, d, m) @@ -366,13 +393,13 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{ case status.Enabled: case status.Disabling: case status.Disabled: - log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", k8s.Status) + log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", cluster.Status) case status.Restoring: } if hasChanged { - k8s, err = utilityK8sCheckPresence(ctx, d, m) - if k8s == nil { + cluster, err = utilityK8sCheckPresence(ctx, d, m) + if cluster == nil { d.SetId("") if err != nil { return diag.FromErr(err) @@ -382,33 +409,64 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{ } if d.HasChange("name") { - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - urlValues.Add("name", d.Get("name").(string)) + req := k8s.UpdateRequest{ + K8SID: cluster.ID, + Name: d.Get("name").(string), + } - _, err := c.DecortAPICall(ctx, "POST", K8sUpdateAPI, urlValues) + _, err := c.CloudAPI().K8S().Update(ctx, req) if err != nil { return diag.FromErr(err) } } if d.HasChange("workers") { - wg := k8s.K8SGroups.Workers[0] - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - urlValues.Add("workersGroupId", strconv.FormatUint(wg.ID, 10)) + wg := cluster.K8SGroups.Workers[0] newWorkers := parseNode(d.Get("workers").([]interface{})) if uint64(newWorkers.Num) > wg.Num { - urlValues.Add("num", strconv.FormatUint(uint64(newWorkers.Num)-wg.Num, 10)) - if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues); err != nil { + req := k8s.WorkerAddRequest{ + K8SID: cluster.ID, + WorkersGroupID: wg.ID, + Num: uint64(newWorkers.Num - int(wg.Num)), + } + + if _, err := c.CloudAPI().K8S().WorkerAdd(ctx, req); err != nil { return diag.FromErr(err) } } else { for i := int(wg.Num) - 1; i >= newWorkers.Num; i-- { - urlValues.Set("workerId", strconv.FormatUint(wg.DetailedInfo[i].ID, 10)) - if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues); err != nil { + req := k8s.DeleteWorkerFromGroupRequest{ + K8SID: cluster.ID, + WorkersGroupID: wg.ID, + WorkerID: wg.DetailedInfo[i].ID, + } + if _, err := c.CloudAPI().K8S().DeleteWorkerFromGroup(ctx, req); err != nil { + return diag.FromErr(err) + } + } + } + } + + if d.HasChange("start") { + if d.Get("start").(bool) { + if cluster.TechStatus == "STOPPED" { + req := k8s.StartRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } + } else { + if cluster.TechStatus == "STARTED" { + req := k8s.StopRequest{ + K8SID: cluster.ID, + } + _, err := c.CloudAPI().K8S().Stop(ctx, req) + if err != nil { return diag.FromErr(err) } } @@ -421,20 +479,18 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{ func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) - k8s, err := utilityK8sCheckPresence(ctx, d, m) - if k8s == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + cluster, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - urlValues.Add("permanently", "true") + req := k8s.DeleteRequest{ + K8SID: cluster.ID, + Permanently: true, + } - _, err = c.DecortAPICall(ctx, "POST", K8sDeleteAPI, urlValues) + _, err = c.CloudAPI().K8S().Delete(ctx, req) if err != nil { return diag.FromErr(err) } @@ -466,6 +522,12 @@ func resourceK8sSchemaMake() map[string]*schema.Schema { Required: true, Description: "Name for first worker group created with cluster.", }, + "network_plugin": { + Type: schema.TypeString, + Required: true, + Description: "Network plugin to be used", + ValidateFunc: validation.StringInSlice([]string{"flannel", "weavenet", "calico"}, true), + }, "labels": { Type: schema.TypeList, Optional: true, @@ -526,6 +588,12 @@ func resourceK8sSchemaMake() map[string]*schema.Schema { Optional: true, Description: "Text description of this instance.", }, + "start": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Start k8s cluster", + }, "acl": { Type: schema.TypeList, diff --git a/internal/service/cloudapi/k8s/resource_k8s_wg.go b/internal/service/cloudapi/k8s/resource_k8s_wg.go index 1a1379d..71823d0 100644 --- a/internal/service/cloudapi/k8s/resource_k8s_wg.go +++ b/internal/service/cloudapi/k8s/resource_k8s_wg.go @@ -34,16 +34,16 @@ package k8s import ( "context" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" ) func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -59,54 +59,26 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("workerNum", strconv.Itoa(d.Get("num").(int))) - urlValues.Add("workerCpu", strconv.Itoa(d.Get("cpu").(int))) - urlValues.Add("workerRam", strconv.Itoa(d.Get("ram").(int))) + req := k8s.WorkersGroupAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + Name: d.Get("name").(string), + WorkerNum: uint64(d.Get("num").(int)), + WorkerCPU: uint64(d.Get("cpu").(int)), + WorkerRAM: uint64(d.Get("ram").(int)), + } if d.Get("disk") == nil { - urlValues.Add("workerDisk", strconv.Itoa(0)) + req.WorkerDisk = 0 } else { - urlValues.Add("workerDisk", strconv.Itoa(d.Get("disk").(int))) + req.WorkerDisk = uint64(d.Get("disk").(int)) } - resp, err := c.DecortAPICall(ctx, "POST", K8sWgCreateAPI, urlValues) + resp, err := c.CloudAPI().K8S().WorkersGroupAdd(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(resp) - - // This code is the supposed flow, but at the time of writing it's not yet implemented by the platfom - - //urlValues = &url.Values{} - //urlValues.Add("auditId", strings.Trim(resp, `"`)) - - //for { - //resp, err := controller.decortAPICall("POST", AsyncTaskGetAPI, urlValues) - //if err != nil { - //return err - //} - - //task := AsyncTask{} - //if err := json.Unmarshal([]byte(resp), &task); err != nil { - //return err - //} - //log.Debugf("resourceK8sCreate: workers group creating - %s", task.Stage) - - //if task.Completed { - //if task.Error != "" { - //return fmt.Errorf("cannot create workers group: %v", task.Error) - //} - - //d.SetId(strconv.Itoa(int(task.Result))) - //break - //} - - //time.Sleep(time.Second * 5) - //} + d.SetId(strconv.FormatUint(resp, 10)) return resourceK8sWgRead(ctx, d, m) } @@ -119,7 +91,7 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{ return diag.FromErr(err) } - workersComputeList := make([]kvmvm.ComputeGetResp, 0, 0) + workersComputeList := make([]compute.RecordCompute, 0, 0) for _, info := range wg.DetailedInfo { compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) if err != nil { @@ -165,20 +137,27 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac return diag.FromErr(err) } - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - urlValues.Add("workersGroupId", d.Id()) - + wgId, _ := strconv.ParseUint(d.Id(), 10, 64) if newNum := d.Get("num").(int); uint64(newNum) > wg.Num { - urlValues.Add("num", strconv.FormatUint(uint64(newNum)-wg.Num, 10)) - _, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues) + req := k8s.WorkerAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wgId, + Num: uint64(newNum) - wg.Num, + } + + _, err := c.CloudAPI().K8S().WorkerAdd(ctx, req) if err != nil { return diag.FromErr(err) } } else { for i := int(wg.Num) - 1; i >= newNum; i-- { - urlValues.Set("workerId", strconv.FormatUint(wg.DetailedInfo[i].ID, 10)) - _, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues) + req := k8s.DeleteWorkerFromGroupRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wgId, + WorkerID: wg.DetailedInfo[i].ID, + } + + _, err := c.CloudAPI().K8S().DeleteWorkerFromGroup(ctx, req) if err != nil { return diag.FromErr(err) } @@ -192,19 +171,17 @@ func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interfac log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int)) wg, err := utilityK8sWgCheckPresence(ctx, d, m) - if wg == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - urlValues.Add("workersGroupId", strconv.FormatUint(wg.ID, 10)) + req := k8s.WorkersGroupDeleteRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + } - _, err = c.DecortAPICall(ctx, "POST", K8sWgDeleteAPI, urlValues) + _, err = c.CloudAPI().K8S().WorkersGroupDelete(ctx, req) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudapi/k8s/utility_k8s.go b/internal/service/cloudapi/k8s/utility_k8s.go index 95baf4f..f79b8ba 100644 --- a/internal/service/cloudapi/k8s/utility_k8s.go +++ b/internal/service/cloudapi/k8s/utility_k8s.go @@ -34,50 +34,37 @@ package k8s import ( "context" - "encoding/json" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" ) -func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8SRecord, error) { +func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8S, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues) - if err != nil { - return nil, err + k8sID, _ := strconv.ParseUint(d.Id(), 10, 64) + req := k8s.GetRequest{ + K8SID: k8sID, } - if resp == "" { - return nil, nil - } - - k8s := K8SRecord{} - if err := json.Unmarshal([]byte(resp), &k8s); err != nil { + k8s, err := c.CloudAPI().K8S().Get(ctx, req) + if err != nil { return nil, err } - return &k8s, nil + return k8s, nil } -func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}, computeID uint64) (*kvmvm.ComputeGetResp, error) { +func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}, computeID uint64) (*compute.RecordCompute, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("computeId", strconv.FormatUint(computeID, 10)) - - computeRaw, err := c.DecortAPICall(ctx, "POST", kvmvm.ComputeGetAPI, urlValues) - if err != nil { - return nil, err + req := compute.GetRequest{ + ComputeID: computeID, } - compute := &kvmvm.ComputeGetResp{} - err = json.Unmarshal([]byte(computeRaw), compute) + compute, err := c.CloudAPI().Compute().Get(ctx, req) if err != nil { return nil, err } @@ -85,41 +72,43 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m return compute, nil } -func utilityDataK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8SRecord, error) { +func utilityDataK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8S, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - k8sRaw, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues) - if err != nil { - return nil, err + req := k8s.GetRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), } - k8s := &K8SRecord{} - err = json.Unmarshal([]byte(k8sRaw), k8s) + k8s, err := c.CloudAPI().K8S().Get(ctx, req) if err != nil { return nil, err } + return k8s, nil } -func utilityK8sListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}, api string) (K8SList, error) { +func utilityK8sListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (k8s.ListK8SClusters, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("includedeleted", "false") - urlValues.Add("page", "0") - urlValues.Add("size", "0") + req := k8s.ListRequest{ + IncludeDeleted: false, + } - k8sListRaw, err := c.DecortAPICall(ctx, "POST", api, urlValues) + k8sList, err := c.CloudAPI().K8S().List(ctx, req) if err != nil { return nil, err } - k8sList := K8SList{} + return k8sList, nil +} + +func utilityK8sListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (k8s.ListK8SClusters, error) { + c := m.(*controller.ControllerCfg) + req := k8s.ListDeletedRequest{} - err = json.Unmarshal([]byte(k8sListRaw), &k8sList) + k8sList, err := c.CloudAPI().K8S().ListDeleted(ctx, req) if err != nil { return nil, err } + return k8sList, nil } diff --git a/internal/service/cloudapi/k8s/utility_k8s_wg.go b/internal/service/cloudapi/k8s/utility_k8s_wg.go index 53a55eb..b5226f2 100644 --- a/internal/service/cloudapi/k8s/utility_k8s_wg.go +++ b/internal/service/cloudapi/k8s/utility_k8s_wg.go @@ -34,40 +34,34 @@ package k8s import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm" ) -func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8SGroup, []kvmvm.ComputeGetResp, error) { +func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ItemK8SGroup, []compute.RecordCompute, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - k8sId := d.Get("k8s_id").(int) - wgId := d.Get("wg_id").(int) + k8sId := uint64(d.Get("k8s_id").(int)) + wgId := uint64(d.Get("wg_id").(int)) - urlValues.Add("k8sId", strconv.Itoa(k8sId)) - - k8sRaw, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues) - if err != nil { - return nil, nil, err + k8sGetReq := k8s.GetRequest{ + K8SID: k8sId, } - k8s := K8SRecord{} - err = json.Unmarshal([]byte(k8sRaw), &k8s) + cluster, err := c.CloudAPI().K8S().Get(ctx, k8sGetReq) if err != nil { return nil, nil, err } - curWg := K8SGroup{} - for _, wg := range k8s.K8SGroups.Workers { - if wg.ID == uint64(wgId) { + curWg := k8s.ItemK8SGroup{} + for _, wg := range cluster.K8SGroups.Workers { + if wg.ID == wgId { curWg = wg break } @@ -76,7 +70,7 @@ func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, return nil, nil, fmt.Errorf("WG with id %v in k8s cluster %v not found", wgId, k8sId) } - workersComputeList := make([]kvmvm.ComputeGetResp, 0, 0) + workersComputeList := make([]compute.RecordCompute, 0, 0) for _, info := range curWg.DetailedInfo { compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID) if err != nil { @@ -89,9 +83,8 @@ func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, return &curWg, workersComputeList, nil } -func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8SGroup, error) { +func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.ItemK8SGroup, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} var wgId int var k8sId int var err error @@ -113,27 +106,34 @@ func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m in k8sId = d.Get("k8s_id").(int) } - urlValues.Add("k8sId", strconv.Itoa(k8sId)) + req := k8s.GetRequest{ + K8SID: uint64(k8sId), + } - resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues) + cluster, err := c.CloudAPI().K8S().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, err + for _, wg := range cluster.K8SGroups.Workers { + if wg.ID == uint64(wgId) { + return &wg, nil + } } - var k8s K8SRecord - if err := json.Unmarshal([]byte(resp), &k8s); err != nil { - return nil, err + return nil, fmt.Errorf("Not found wg with id: %v in k8s cluster: %v", wgId, cluster.ID) +} + +func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (k8s.ListK8SGroups, error) { + c := m.(*controller.ControllerCfg) + req := k8s.GetRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), } - for _, wg := range k8s.K8SGroups.Workers { - if wg.ID == uint64(wgId) { - return &wg, nil - } + cluster, err := c.CloudAPI().K8S().Get(ctx, req) + if err != nil { + return nil, err } - return nil, fmt.Errorf("Not found wg with id: %v in k8s cluster: %v", wgId, k8s.ID) + return cluster.K8SGroups.Workers, nil } diff --git a/internal/service/cloudapi/kvmvm/api.go b/internal/service/cloudapi/kvmvm/api.go deleted file mode 100644 index cb88155..0000000 --- a/internal/service/cloudapi/kvmvm/api.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package kvmvm - -const ( - KvmX86CreateAPI = "/restmachine/cloudapi/kvmx86/create" - KvmPPCCreateAPI = "/restmachine/cloudapi/kvmppc/create" - ComputeGetAPI = "/restmachine/cloudapi/compute/get" - RgListComputesAPI = "/restmachine/cloudapi/rg/listComputes" - ComputeNetAttachAPI = "/restmachine/cloudapi/compute/netAttach" - ComputeNetDetachAPI = "/restmachine/cloudapi/compute/netDetach" - ComputeDiskAttachAPI = "/restmachine/cloudapi/compute/diskAttach" - ComputeDiskDetachAPI = "/restmachine/cloudapi/compute/diskDetach" - ComputeStartAPI = "/restmachine/cloudapi/compute/start" - ComputeStopAPI = "/restmachine/cloudapi/compute/stop" - ComputeResizeAPI = "/restmachine/cloudapi/compute/resize" - DisksResizeAPI = "/restmachine/cloudapi/disks/resize2" - ComputeDeleteAPI = "/restmachine/cloudapi/compute/delete" - ComputeUpdateAPI = "/restmachine/cloudapi/compute/update" - ComputeDiskAddAPI = "/restmachine/cloudapi/compute/diskAdd" - ComputeDiskDeleteAPI = "/restmachine/cloudapi/compute/diskDel" - ComputeRestoreAPI = "/restmachine/cloudapi/compute/restore" - ComputeEnableAPI = "/restmachine/cloudapi/compute/enable" - ComputeDisableAPI = "/restmachine/cloudapi/compute/disable" - ComputeAffinityLabelSetAPI = "/restmachine/cloudapi/compute/affinityLabelSet" - ComputeAffinityLabelRemoveAPI = "/restmachine/cloudapi/compute/affinityLabelRemove" - ComputeAffinityRuleAddAPI = "/restmachine/cloudapi/compute/affinityRuleAdd" - ComputeAffinityRuleRemoveAPI = "/restmachine/cloudapi/compute/affinityRuleRemove" - ComputeAffinityRulesClearAPI = "/restmachine/cloudapi/compute/affinityRulesClear" - ComputeAntiAffinityRuleAddAPI = "/restmachine/cloudapi/compute/antiAffinityRuleAdd" - ComputeAntiAffinityRuleRemoveAPI = "/restmachine/cloudapi/compute/antiAffinityRuleRemove" - ComputeAntiAffinityRulesClearAPI = "/restmachine/cloudapi/compute/antiAffinityRulesClear" - ComputeListAPI = "/restmachine/cloudapi/compute/list" - ComputeAuditsAPI = "/restmachine/cloudapi/compute/audits" - ComputeGetAuditsAPI = "/restmachine/cloudapi/compute/getAudits" - ComputeGetConsoleUrlAPI = "/restmachine/cloudapi/compute/getConsoleUrl" - ComputeGetLogAPI = "/restmachine/cloudapi/compute/getLog" - ComputePfwListAPI = "/restmachine/cloudapi/compute/pfwList" - ComputeUserListAPI = "/restmachine/cloudapi/compute/userList" - ComputeTagAddAPI = "/restmachine/cloudapi/compute/tagAdd" - ComputeTagRemoveAPI = "/restmachine/cloudapi/compute/tagRemove" - ComputePinToStackAPI = "/restmachine/cloudapi/compute/pinToStack" - ComputeUnpinFromStackAPI = "/restmachine/cloudapi/compute/unpinFromStack" - ComputePfwAddAPI = "/restmachine/cloudapi/compute/pfwAdd" - ComputePfwDelAPI = "/restmachine/cloudapi/compute/pfwDel" - ComputeUserGrantAPI = "/restmachine/cloudapi/compute/userGrant" - ComputeUserRevokeAPI = "/restmachine/cloudapi/compute/userRevoke" - ComputeSnapshotCreateAPI = "/restmachine/cloudapi/compute/snapshotCreate" - ComputeSnapshotDeleteAPI = "/restmachine/cloudapi/compute/snapshotCreate" - ComputeSnapshotUsageAPI = "/restmachine/cloudapi/compute/snapshotUsage" - ComputeSnapshotRollbackAPI = "/restmachine/cloudapi/compute/snapshotRollback" - ComputePauseAPI = "/restmachine/cloudapi/compute/pause" - ComputeResumeAPI = "/restmachine/cloudapi/compute/resume" - ComputeCdInsertAPI = "/restmachine/cloudapi/compute/cdInsert" - ComputeCdEjectAPI = "/restmachine/cloudapi/compute/cdEject" - ComputeResetAPI = "/restmachine/cloudapi/compute/reset" - ComputeRedeployAPI = "/restmachine/cloudapi/compute/redeploy" -) diff --git a/internal/service/cloudapi/kvmvm/data_source_compute_snapshot_usage.go b/internal/service/cloudapi/kvmvm/data_source_compute_snapshot_usage.go index 0af3cf0..3b7c7c4 100644 --- a/internal/service/cloudapi/kvmvm/data_source_compute_snapshot_usage.go +++ b/internal/service/cloudapi/kvmvm/data_source_compute_snapshot_usage.go @@ -10,7 +10,7 @@ import ( ) func dataSourceComputeSnapshotUsageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - computeSnapshotUsage, err := utilityComputeSnapshotUasgeCheckPresence(ctx, d, m) + computeSnapshotUsage, err := utilityComputeSnapshotUsageCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudapi/kvmvm/flattens.go b/internal/service/cloudapi/kvmvm/flattens.go index 1eb30be..8bf0b8d 100644 --- a/internal/service/cloudapi/kvmvm/flattens.go +++ b/internal/service/cloudapi/kvmvm/flattens.go @@ -39,10 +39,11 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" ) -func flattenDisks(disks []InfoDisk) []map[string]interface{} { +func flattenDisks(disks []compute.InfoDisk) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, disk := range disks { temp := map[string]interface{}{ @@ -53,7 +54,7 @@ func flattenDisks(disks []InfoDisk) []map[string]interface{} { } return res } -func flattenQOS(qos QOS) []map[string]interface{} { +func flattenQOS(qos compute.QOS) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "e_rate": qos.ERate, @@ -64,7 +65,7 @@ func flattenQOS(qos QOS) []map[string]interface{} { res = append(res, temp) return res } -func flattenInterfaces(interfaces ListInterfaces) []map[string]interface{} { +func flattenInterfaces(interfaces compute.ListInterfaces) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, interfaceItem := range interfaces { temp := map[string]interface{}{ @@ -90,7 +91,7 @@ func flattenInterfaces(interfaces ListInterfaces) []map[string]interface{} { } return res } -func flattenSnapSets(snapSets ListSnapSets) []map[string]interface{} { +func flattenSnapSets(snapSets compute.ListSnapSets) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, snapSet := range snapSets { temp := map[string]interface{}{ @@ -115,7 +116,7 @@ func flattenTags(tags map[string]string) []map[string]interface{} { return res } -func flattenListRules(listRules ListRules) []map[string]interface{} { +func flattenListRules(listRules compute.ListRules) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rule := range listRules { temp := map[string]interface{}{ @@ -130,18 +131,11 @@ func flattenListRules(listRules ListRules) []map[string]interface{} { } return res } -func flattenListACL(listAcl ListACL) []map[string]interface{} { +func flattenListACL(listAcl compute.ListACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, acl := range listAcl { - var explicit interface{} - switch acl.Explicit.(type) { //Платформенный хак - case bool: - explicit = acl.Explicit.(bool) - case string: - explicit, _ = strconv.ParseBool(acl.Explicit.(string)) - } temp := map[string]interface{}{ - "explicit": explicit, + "explicit": acl.Explicit, "guid": acl.GUID, "right": acl.Right, "status": acl.Status, @@ -152,7 +146,8 @@ func flattenListACL(listAcl ListACL) []map[string]interface{} { } return res } -func flattenComputeList(computes ListComputes) []map[string]interface{} { + +func flattenComputeList(computes compute.ListComputes) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, compute := range computes { customFields, _ := json.Marshal(compute.CustomFields) @@ -219,7 +214,29 @@ func flattenComputeList(computes ListComputes) []map[string]interface{} { return res } -func flattenComputeDisksDemo(disksList ListComputeDisks, extraDisks []interface{}) []map[string]interface{} { +func flattenBootDisk(bootDisk *compute.ItemComputeDisk) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + + temp := map[string]interface{}{ + "disk_name": bootDisk.Name, + "disk_id": bootDisk.ID, + "disk_type": bootDisk.Type, + "sep_id": bootDisk.SepID, + "shareable": bootDisk.Shareable, + "size_max": bootDisk.SizeMax, + "size_used": bootDisk.SizeUsed, + "pool": bootDisk.Pool, + "desc": bootDisk.Description, + "image_id": bootDisk.ImageID, + "size": bootDisk.SizeMax, + } + + res = append(res, temp) + + return res +} + +func flattenComputeDisksDemo(disksList compute.ListComputeDisks, extraDisks []interface{}) []map[string]interface{} { res := make([]map[string]interface{}, 0, len(disksList)) for _, disk := range disksList { if disk.Name == "bootdisk" || findInExtraDisks(uint(disk.ID), extraDisks) { //skip main bootdisk and extraDisks @@ -246,7 +263,7 @@ func flattenComputeDisksDemo(disksList ListComputeDisks, extraDisks []interface{ return res } -func flattenNetwork(interfaces ListInterfaces) []map[string]interface{} { +func flattenNetwork(interfaces compute.ListInterfaces) []map[string]interface{} { res := make([]map[string]interface{}, 0, len(interfaces)) //index := 0 for _, network := range interfaces { @@ -261,7 +278,7 @@ func flattenNetwork(interfaces ListInterfaces) []map[string]interface{} { return res } -func findBootDisk(disks ListComputeDisks) *ItemComputeDisk { +func findBootDisk(disks compute.ListComputeDisks) *compute.ItemComputeDisk { for _, disk := range disks { if disk.Name == "bootdisk" { return &disk @@ -270,139 +287,109 @@ func findBootDisk(disks ListComputeDisks) *ItemComputeDisk { return nil } -func flattenCompute(d *schema.ResourceData, compute RecordCompute) error { +func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute) error { // This function expects that compFacts string contains response from API compute/get, // i.e. detailed information about compute instance. // // NOTE: this function modifies ResourceData argument - as such it should never be called // from resourceComputeExists(...) method - log.Debugf("flattenCompute: ID %d, RG ID %d", compute.ID, compute.RGID) + log.Debugf("flattenCompute: ID %d, RG ID %d", computeRec.ID, computeRec.RGID) - devices, _ := json.Marshal(compute.Devices) - userdata, _ := json.Marshal(compute.Userdata) + devices, _ := json.Marshal(computeRec.Devices) + userdata, _ := json.Marshal(computeRec.Userdata) + bootDisk := findBootDisk(computeRec.Disks) //check extraDisks, ipa_type, is, - d.SetId(strconv.FormatUint(compute.ID, 10)) - d.Set("acl", flattenACL(compute.ACL)) - d.Set("account_id", compute.AccountID) - d.Set("account_name", compute.AccountName) - d.Set("affinity_weight", compute.AffinityWeight) - d.Set("arch", compute.Architecture) - d.Set("boot_order", compute.BootOrder) - d.Set("boot_disk_size", compute.BootDiskSize) - bootDisk := findBootDisk(compute.Disks) + d.SetId(strconv.FormatUint(computeRec.ID, 10)) + d.Set("acl", flattenACL(computeRec.ACL)) + d.Set("account_id", computeRec.AccountID) + d.Set("account_name", computeRec.AccountName) + d.Set("affinity_weight", computeRec.AffinityWeight) + d.Set("arch", computeRec.Architecture) + d.Set("boot_order", computeRec.BootOrder) + d.Set("boot_disk_size", computeRec.BootDiskSize) + d.Set("boot_disk", flattenBootDisk(bootDisk)) d.Set("boot_disk_id", bootDisk.ID) d.Set("sep_id", bootDisk.SepID) d.Set("pool", bootDisk.Pool) - d.Set("clone_reference", compute.CloneReference) - d.Set("clones", compute.Clones) + d.Set("clone_reference", computeRec.CloneReference) + d.Set("clones", computeRec.Clones) if string(userdata) != "{}" { d.Set("cloud_init", string(userdata)) } - d.Set("computeci_id", compute.ComputeCIID) - d.Set("created_by", compute.CreatedBy) - d.Set("created_time", compute.CreatedTime) - d.Set("custom_fields", flattenCustomFields(compute.CustomFields)) - d.Set("deleted_by", compute.DeletedBy) - d.Set("deleted_time", compute.DeletedTime) - d.Set("description", compute.Description) + d.Set("computeci_id", computeRec.ComputeCIID) + d.Set("created_by", computeRec.CreatedBy) + d.Set("created_time", computeRec.CreatedTime) + d.Set("custom_fields", flattenCustomFields(computeRec.CustomFields)) + d.Set("deleted_by", computeRec.DeletedBy) + d.Set("deleted_time", computeRec.DeletedTime) + d.Set("description", computeRec.Description) d.Set("devices", string(devices)) - err := d.Set("disks", flattenComputeDisksDemo(compute.Disks, d.Get("extra_disks").(*schema.Set).List())) + err := d.Set("disks", flattenComputeDisksDemo(computeRec.Disks, d.Get("extra_disks").(*schema.Set).List())) if err != nil { return err } - d.Set("driver", compute.Driver) - d.Set("cpu", compute.CPU) - d.Set("gid", compute.GID) - d.Set("guid", compute.GUID) - d.Set("compute_id", compute.ID) - if compute.VirtualImageID != 0 { - d.Set("image_id", compute.VirtualImageID) + d.Set("driver", computeRec.Driver) + d.Set("cpu", computeRec.CPU) + d.Set("gid", computeRec.GID) + d.Set("guid", computeRec.GUID) + d.Set("compute_id", computeRec.ID) + if computeRec.VirtualImageID != 0 { + d.Set("image_id", computeRec.VirtualImageID) } else { - d.Set("image_id", compute.ImageID) + d.Set("image_id", computeRec.ImageID) } - d.Set("interfaces", flattenInterfaces(compute.Interfaces)) - d.Set("lock_status", compute.LockStatus) - d.Set("manager_id", compute.ManagerID) - d.Set("manager_type", compute.ManagerType) - d.Set("migrationjob", compute.MigrationJob) - d.Set("milestones", compute.Milestones) - d.Set("name", compute.Name) - d.Set("natable_vins_id", compute.NatableVINSID) - d.Set("natable_vins_ip", compute.NatableVINSIP) - d.Set("natable_vins_name", compute.NatableVINSName) - d.Set("natable_vins_network", compute.NatableVINSNetwork) - d.Set("natable_vins_network_name", compute.NatableVINSNetworkName) - if err := d.Set("os_users", parseOsUsers(compute.OSUsers)); err != nil { + d.Set("interfaces", flattenInterfaces(computeRec.Interfaces)) + d.Set("lock_status", computeRec.LockStatus) + d.Set("manager_id", computeRec.ManagerID) + d.Set("manager_type", computeRec.ManagerType) + d.Set("migrationjob", computeRec.MigrationJob) + d.Set("milestones", computeRec.Milestones) + d.Set("name", computeRec.Name) + d.Set("natable_vins_id", computeRec.NatableVINSID) + d.Set("natable_vins_ip", computeRec.NatableVINSIP) + d.Set("natable_vins_name", computeRec.NatableVINSName) + d.Set("natable_vins_network", computeRec.NatableVINSNetwork) + d.Set("natable_vins_network_name", computeRec.NatableVINSNetworkName) + if err := d.Set("os_users", parseOsUsers(computeRec.OSUsers)); err != nil { return err } - d.Set("pinned", compute.Pinned) - d.Set("ram", compute.RAM) - d.Set("reference_id", compute.ReferenceID) - d.Set("registered", compute.Registered) - d.Set("res_name", compute.ResName) - d.Set("rg_id", compute.RGID) - d.Set("rg_name", compute.RGName) - d.Set("snap_sets", flattenSnapSets(compute.SnapSets)) - d.Set("stateless_sep_id", compute.StatelessSepID) - d.Set("stateless_sep_type", compute.StatelessSepType) - d.Set("status", compute.Status) - d.Set("tags", flattenTags(compute.Tags)) - d.Set("tech_status", compute.TechStatus) - d.Set("updated_by", compute.UpdatedBy) - d.Set("updated_time", compute.UpdatedTime) - d.Set("user_managed", compute.UserManaged) - d.Set("vgpus", compute.VGPUs) - d.Set("virtual_image_id", compute.VirtualImageID) - d.Set("virtual_image_name", compute.VirtualImageName) + d.Set("pinned", computeRec.Pinned) + d.Set("ram", computeRec.RAM) + d.Set("reference_id", computeRec.ReferenceID) + d.Set("registered", computeRec.Registered) + d.Set("res_name", computeRec.ResName) + d.Set("rg_id", computeRec.RGID) + d.Set("rg_name", computeRec.RGName) + d.Set("snap_sets", flattenSnapSets(computeRec.SnapSets)) + d.Set("stateless_sep_id", computeRec.StatelessSepID) + d.Set("stateless_sep_type", computeRec.StatelessSepType) + d.Set("status", computeRec.Status) + d.Set("tags", flattenTags(computeRec.Tags)) + d.Set("tech_status", computeRec.TechStatus) + d.Set("updated_by", computeRec.UpdatedBy) + d.Set("updated_time", computeRec.UpdatedTime) + d.Set("user_managed", computeRec.UserManaged) + d.Set("vgpus", computeRec.VGPUs) + d.Set("virtual_image_id", computeRec.VirtualImageID) + d.Set("virtual_image_name", computeRec.VirtualImageName) d.Set("enabled", false) - if compute.Status == status.Enabled { + if computeRec.Status == status.Enabled { d.Set("enabled", true) } d.Set("started", false) - if compute.TechStatus == "STARTED" { + if computeRec.TechStatus == "STARTED" { d.Set("started", true) } - d.Set("network", flattenNetwork(compute.Interfaces)) - - //if len(model.Disks) > 0 { - //log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks)) - //if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil { - //return err - //} - //} + d.Set("network", flattenNetwork(computeRec.Interfaces)) return nil } -func flattenDataComputeDisksDemo(disksList ListComputeDisks, extraDisks []interface{}) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, disk := range disksList { - if findInExtraDisks(uint(disk.ID), extraDisks) { //skip main bootdisk and extraDisks - continue - } - temp := map[string]interface{}{ - "disk_name": disk.Name, - "disk_id": disk.ID, - "disk_type": disk.Type, - "sep_id": disk.SepID, - "shareable": disk.Shareable, - "size_max": disk.SizeMax, - "size_used": disk.SizeUsed, - "pool": disk.Pool, - "desc": disk.Description, - "image_id": disk.ImageID, - "size": disk.SizeMax, - } - res = append(res, temp) - } - return res -} - -func flattenACL(acl RecordACL) []map[string]interface{} { +func flattenACL(acl compute.RecordACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "account_acl": flattenListACL(acl.AccountACL), @@ -413,7 +400,7 @@ func flattenACL(acl RecordACL) []map[string]interface{} { return res } -func flattenAffinityRules(affinityRules ListRules) []map[string]interface{} { +func flattenAffinityRules(affinityRules compute.ListRules) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, affinityRule := range affinityRules { temp := map[string]interface{}{ @@ -430,7 +417,7 @@ func flattenAffinityRules(affinityRules ListRules) []map[string]interface{} { return res } -func flattenIotune(iotune IOTune) []map[string]interface{} { +func flattenIotune(iotune compute.IOTune) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "read_bytes_sec": iotune.ReadBytesSec, @@ -452,7 +439,7 @@ func flattenIotune(iotune IOTune) []map[string]interface{} { return res } -func flattenSnapshots(snapshots SnapshotExtendList) []map[string]interface{} { +func flattenSnapshots(snapshots compute.SnapshotExtendList) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, snapshot := range snapshots { temp := map[string]interface{}{ @@ -469,7 +456,7 @@ func flattenSnapshots(snapshots SnapshotExtendList) []map[string]interface{} { return res } -func flattenListComputeDisks(disks ListComputeDisks) []map[string]interface{} { +func flattenListComputeDisks(disks compute.ListComputeDisks) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, disk := range disks { acl, _ := json.Marshal(disk.ACL) @@ -532,7 +519,7 @@ func flattenCustomFields(customFileds map[string]interface{}) []map[string]inter } return res } -func flattenOsUsers(osUsers ListOSUser) []map[string]interface{} { +func flattenOsUsers(osUsers compute.ListOSUser) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, user := range osUsers { temp := map[string]interface{}{ @@ -546,72 +533,72 @@ func flattenOsUsers(osUsers ListOSUser) []map[string]interface{} { return res } -func flattenDataCompute(d *schema.ResourceData, compute RecordCompute) { - devices, _ := json.Marshal(compute.Devices) - userdata, _ := json.Marshal(compute.Userdata) - d.Set("acl", flattenACL(compute.ACL)) - d.Set("account_id", compute.AccountID) - d.Set("account_name", compute.AccountName) - d.Set("affinity_label", compute.AffinityLabel) - d.Set("affinity_rules", flattenAffinityRules(compute.AffinityRules)) - d.Set("affinity_weight", compute.AffinityWeight) - d.Set("anti_affinity_rules", flattenListRules(compute.AntiAffinityRules)) - d.Set("arch", compute.Architecture) - d.Set("boot_order", compute.BootOrder) - d.Set("bootdisk_size", compute.BootDiskSize) - d.Set("clone_reference", compute.CloneReference) - d.Set("clones", compute.Clones) - d.Set("computeci_id", compute.ComputeCIID) - d.Set("cpus", compute.CPU) - d.Set("created_by", compute.CreatedBy) - d.Set("created_time", compute.CreatedTime) - d.Set("custom_fields", flattenCustomFields(compute.CustomFields)) - d.Set("deleted_by", compute.DeletedBy) - d.Set("deleted_time", compute.DeletedTime) - d.Set("desc", compute.Description) +func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute) { + devices, _ := json.Marshal(computeRec.Devices) + userdata, _ := json.Marshal(computeRec.Userdata) + d.Set("acl", flattenACL(computeRec.ACL)) + d.Set("account_id", computeRec.AccountID) + d.Set("account_name", computeRec.AccountName) + d.Set("affinity_label", computeRec.AffinityLabel) + d.Set("affinity_rules", flattenAffinityRules(computeRec.AffinityRules)) + d.Set("affinity_weight", computeRec.AffinityWeight) + d.Set("anti_affinity_rules", flattenListRules(computeRec.AntiAffinityRules)) + d.Set("arch", computeRec.Architecture) + d.Set("boot_order", computeRec.BootOrder) + d.Set("bootdisk_size", computeRec.BootDiskSize) + d.Set("clone_reference", computeRec.CloneReference) + d.Set("clones", computeRec.Clones) + d.Set("computeci_id", computeRec.ComputeCIID) + d.Set("cpus", computeRec.CPU) + d.Set("created_by", computeRec.CreatedBy) + d.Set("created_time", computeRec.CreatedTime) + d.Set("custom_fields", flattenCustomFields(computeRec.CustomFields)) + d.Set("deleted_by", computeRec.DeletedBy) + d.Set("deleted_time", computeRec.DeletedTime) + d.Set("desc", computeRec.Description) d.Set("devices", string(devices)) - d.Set("disks", flattenListComputeDisks(compute.Disks)) - d.Set("driver", compute.Driver) - d.Set("gid", compute.GID) - d.Set("guid", compute.GUID) - d.Set("compute_id", compute.ID) - d.Set("image_id", compute.ImageID) - d.Set("interfaces", flattenInterfaces(compute.Interfaces)) - d.Set("lock_status", compute.LockStatus) - d.Set("manager_id", compute.ManagerID) - d.Set("manager_type", compute.ManagerType) - d.Set("migrationjob", compute.MigrationJob) - d.Set("milestones", compute.Milestones) - d.Set("name", compute.Name) - d.Set("natable_vins_id", compute.NatableVINSID) - d.Set("natable_vins_ip", compute.NatableVINSIP) - d.Set("natable_vins_name", compute.NatableVINSName) - d.Set("natable_vins_network", compute.NatableVINSNetwork) - d.Set("natable_vins_network_name", compute.NatableVINSNetworkName) - d.Set("os_users", flattenOsUsers(compute.OSUsers)) - d.Set("pinned", compute.Pinned) - d.Set("ram", compute.RAM) - d.Set("reference_id", compute.ReferenceID) - d.Set("registered", compute.Registered) - d.Set("res_name", compute.ResName) - d.Set("rg_id", compute.RGID) - d.Set("rg_name", compute.RGName) - d.Set("snap_sets", flattenSnapSets(compute.SnapSets)) - d.Set("stateless_sep_id", compute.StatelessSepID) - d.Set("stateless_sep_type", compute.StatelessSepType) - d.Set("status", compute.Status) - d.Set("tags", compute.Tags) - d.Set("tech_status", compute.TechStatus) - d.Set("updated_by", compute.UpdatedBy) - d.Set("updated_time", compute.UpdatedTime) - d.Set("user_managed", compute.UserManaged) + d.Set("disks", flattenListComputeDisks(computeRec.Disks)) + d.Set("driver", computeRec.Driver) + d.Set("gid", computeRec.GID) + d.Set("guid", computeRec.GUID) + d.Set("compute_id", computeRec.ID) + d.Set("image_id", computeRec.ImageID) + d.Set("interfaces", flattenInterfaces(computeRec.Interfaces)) + d.Set("lock_status", computeRec.LockStatus) + d.Set("manager_id", computeRec.ManagerID) + d.Set("manager_type", computeRec.ManagerType) + d.Set("migrationjob", computeRec.MigrationJob) + d.Set("milestones", computeRec.Milestones) + d.Set("name", computeRec.Name) + d.Set("natable_vins_id", computeRec.NatableVINSID) + d.Set("natable_vins_ip", computeRec.NatableVINSIP) + d.Set("natable_vins_name", computeRec.NatableVINSName) + d.Set("natable_vins_network", computeRec.NatableVINSNetwork) + d.Set("natable_vins_network_name", computeRec.NatableVINSNetworkName) + d.Set("os_users", flattenOsUsers(computeRec.OSUsers)) + d.Set("pinned", computeRec.Pinned) + d.Set("ram", computeRec.RAM) + d.Set("reference_id", computeRec.ReferenceID) + d.Set("registered", computeRec.Registered) + d.Set("res_name", computeRec.ResName) + d.Set("rg_id", computeRec.RGID) + d.Set("rg_name", computeRec.RGName) + d.Set("snap_sets", flattenSnapSets(computeRec.SnapSets)) + d.Set("stateless_sep_id", computeRec.StatelessSepID) + d.Set("stateless_sep_type", computeRec.StatelessSepType) + d.Set("status", computeRec.Status) + d.Set("tags", computeRec.Tags) + d.Set("tech_status", computeRec.TechStatus) + d.Set("updated_by", computeRec.UpdatedBy) + d.Set("updated_time", computeRec.UpdatedTime) + d.Set("user_managed", computeRec.UserManaged) d.Set("userdata", string(userdata)) - d.Set("vgpus", compute.VGPUs) - d.Set("virtual_image_id", compute.VirtualImageID) - d.Set("virtual_image_name", compute.VirtualImageName) + d.Set("vgpus", computeRec.VGPUs) + d.Set("virtual_image_id", computeRec.VirtualImageID) + d.Set("virtual_image_name", computeRec.VirtualImageName) } -func flattenComputeAudits(computeAudits ListAudits) []map[string]interface{} { +func flattenComputeAudits(computeAudits compute.ListAudits) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, computeAudit := range computeAudits { temp := map[string]interface{}{ @@ -626,7 +613,7 @@ func flattenComputeAudits(computeAudits ListAudits) []map[string]interface{} { return res } -func flattenPfwList(computePfws ListPFWs) []map[string]interface{} { +func flattenPfwList(computePfws compute.ListPFWs) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, computePfw := range computePfws { temp := map[string]interface{}{ @@ -643,13 +630,13 @@ func flattenPfwList(computePfws ListPFWs) []map[string]interface{} { return res } -func flattenUserList(d *schema.ResourceData, userList RecordACL) { +func flattenUserList(d *schema.ResourceData, userList compute.RecordACL) { d.Set("account_acl", flattenListACL(userList.AccountACL)) d.Set("compute_acl", flattenListACL(userList.ComputeACL)) d.Set("rg_acl", flattenListACL(userList.RGACL)) } -func flattenComputeGetAudits(computeAudits ListShortAudits) []map[string]interface{} { +func flattenComputeGetAudits(computeAudits compute.ListShortAudits) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, computeAudit := range computeAudits { temp := map[string]interface{}{ @@ -661,9 +648,9 @@ func flattenComputeGetAudits(computeAudits ListShortAudits) []map[string]interfa return res } -func flattenSnapshotUsage(computeSnapshotUasges ListUsageSnapshots) []map[string]interface{} { +func flattenSnapshotUsage(computeSnapshotUsages compute.ListUsageSnapshots) []map[string]interface{} { res := make([]map[string]interface{}, 0) - for _, computeUsage := range computeSnapshotUasges { + for _, computeUsage := range computeSnapshotUsages { temp := map[string]interface{}{ "count": computeUsage.Count, "stored": computeUsage.Stored, diff --git a/internal/service/cloudapi/kvmvm/models.go b/internal/service/cloudapi/kvmvm/models.go deleted file mode 100644 index 98fde45..0000000 --- a/internal/service/cloudapi/kvmvm/models.go +++ /dev/null @@ -1,1077 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package kvmvm - -type DiskRecord struct { - Acl map[string]interface{} `json:"acl"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - BootPartition int `json:"bootPartition"` - CreatedTime uint64 `json:"creationTime"` - ComputeID int `json:"computeId"` - ComputeName string `json:"computeName"` - DeletedTime uint64 `json:"deletionTime"` - DeviceName string `json:"devicename"` - Desc string `json:"desc"` - DestructionTime uint64 `json:"destructionTime"` - DiskPath string `json:"diskPath"` - GridID int `json:"gid"` - GUID int `json:"guid"` - ID uint `json:"id"` - ImageID int `json:"imageId"` - Images []int `json:"images"` - IOTune map[string]interface{} `json:"iotune"` - IQN string `json:"iqn"` - Login string `json:"login"` - Name string `json:"name"` - MachineId int `json:"machineId"` - MachineName string `json:"machineName"` - Milestones uint64 `json:"milestones"` - Order int `json:"order"` - Params string `json:"params"` - Passwd string `json:"passwd"` - ParentId int `json:"parentId"` - PciSlot int `json:"pciSlot"` - Pool string `json:"pool"` - PurgeTime uint64 `json:"purgeTime"` - PurgeAttempts uint64 `json:"purgeAttempts"` - RealityDeviceNumber int `json:"realityDeviceNumber"` - ReferenceId string `json:"referenceId"` - ResID string `json:"resId"` - ResName string `json:"resName"` - Role string `json:"role"` - SepType string `json:"sepType"` - SepID int `json:"sepId"` // NOTE: absent from compute/get output - Shareable bool `json:"shareable"` - SizeMax int `json:"sizeMax"` - SizeUsed float64 `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space - Snapshots []SnapshotRecord `json:"snapshots"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` - UpdateBy uint64 `json:"updateBy"` - VMID int `json:"vmid"` -} - -type InterfaceRecord struct { - ConnID int `json:"connId"` // This is VLAN ID or VxLAN ID, depending on ConnType - ConnType string `json:"connType"` // Either "VLAN" or "VXLAN" tag - DefaultGW string `json:"defGw"` - Guid string `json:"guid"` - IPAddress string `json:"ipAddress"` // without trailing network mask, i.e. "192.168.1.3" - MAC string `json:"mac"` - Name string `json:"name"` - NetID int `json:"netId"` // This is either ExtNet ID or ViNS ID, depending on NetType - NetMask int `json:"netMask"` - NetType string `json:"netType"` // Either "EXTNET" or "VINS" tag - PciSlot int `json:"pciSlot"` - Target string `json:"target"` - Type string `json:"type"` - VNFs []int `json:"vnfs"` - QOS InterfaceQosRecord `json:"qos"` -} - -type InterfaceQosRecord struct { - ERate int `json:"eRate"` - Guid string `json:"guid"` - InBurst int `json:"inBurst"` - InRate int `json:"inRate"` -} - -type SnapshotRecord struct { - Guid string `json:"guid"` - Label string `json:"label"` - ResId string `json:"resId"` - SnapSetGuid string `json:"snapSetGuid"` - SnapSetTime uint64 `json:"snapSetTime"` - TimeStamp uint64 `json:"timestamp"` -} - -//type SnapshotRecordList []SnapshotRecord - -type ComputeGetResp struct { - // ACLs `json:"ACL"` - it is a dictionary, special parsing required - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - Arch string `json:"arch"` - BootDiskSize int `json:"bootdiskSize"` - CloneReference int `json:"cloneReference"` - Clones []int `json:"clones"` - Cpu int `json:"cpus"` - Desc string `json:"desc"` - Disks []DiskRecord `json:"disks"` - Driver string `json:"driver"` - GridID int `json:"gid"` - ID uint `json:"id"` - ImageID int `json:"imageId"` - ImageName string `json:"imageName"` - Interfaces []InterfaceRecord `json:"interfaces"` - LockStatus string `json:"lockStatus"` - ManagerID int `json:"managerId"` - ManagerType string `json:"manageType"` - Name string `json:"name"` - NatableVinsID int `json:"natableVinsId"` - NatableVinsIP string `json:"natableVinsIp"` - NatableVinsName string `json:"natableVinsName"` - NatableVinsNet string `json:"natableVinsNetwork"` - NatableVinsNetName string `json:"natableVinsNetworkName"` - OsUsers []OsUserRecord `json:"osUsers"` - Ram int `json:"ram"` - RgID int `json:"rgId"` - RgName string `json:"rgName"` - SnapSets []SnapSetRecord `json:"snapSets"` - Status string `json:"status"` - // Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1 - TechStatus string `json:"techStatus"` - TotalDiskSize int `json:"totalDiskSize"` - UpdatedBy string `json:"updatedBy"` - UpdateTime uint64 `json:"updateTime"` - UserManaged bool `json:"userManaged"` - Vgpus []int `json:"vgpus"` - VinsConnected int `json:"vinsConnected"` - VirtualImageID int `json:"virtualImageId"` -} - -type OsUserRecord struct { - Guid string `json:"guid"` - Login string `json:"login"` - Password string `json:"password"` - PubKey string `json:"pubkey"` -} - -type SnapSetRecord struct { - Disks []int `json:"disks"` - Guid string `json:"guid"` - Label string `json:"label"` - TimeStamp uint64 `json:"timestamp"` -} - -type ComputeBriefRecord struct { // this is a brief compute specifiaction as returned by API rg/listComputes - // we do not even include here all fields as returned by this API, but only the most important that - // are really necessary to identify and distinguish computes - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - Name string `json:"name"` - ID uint `json:"id"` - RgID int `json:"rgId"` - RgName string `json:"rgName"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` -} - -type RgListComputesResp []ComputeBriefRecord - -//############# - -// Access Control List -type RecordACL struct { - // Account ACL list - AccountACL ListACL `json:"accountAcl"` - - // Compute ACL list - ComputeACL ListACL `json:"computeAcl"` - - // Resource group ACL list - RGACL ListACL `json:"rgAcl"` -} - -// ACL information -type ItemACL struct { - // Explicit - Explicit interface{} `json:"explicit"` - - // GUID - GUID string `json:"guid"` - - // Right - Right string `json:"right"` - - // Status - Status string `json:"status"` - - // Type - Type string `json:"type"` - - // User group ID - UserGroupID string `json:"userGroupId"` -} - -// List ACL -type ListACL []ItemACL - -// Main information about usage snapshot -type ItemUsageSnapshot struct { - // Count - Count uint64 `json:"count,omitempty"` - - // Stored - Stored float64 `json:"stored"` - - // Label - Label string `json:"label,omitempty"` - - // Timestamp - Timestamp uint64 `json:"timestamp,omitempty"` -} - -// List of usage snapshot -type ListUsageSnapshots []ItemUsageSnapshot - -// Main information about snapshot -type ItemSnapshot struct { - // List disk ID - Disks []uint64 `json:"disks"` - - // GUID - GUID string `json:"guid"` - - // Label - Label string `json:"label"` - - // Timestamp - Timestamp uint64 `json:"timestamp"` -} - -// List of snapshots -type ListSnapShots []ItemSnapshot - -// Main information about port forward -type ItemPFW struct { - // ID - ID uint64 `json:"id"` - - // Local IP - LocalIP string `json:"localIp"` - - // Local port - LocalPort uint64 `json:"localPort"` - - // Protocol - Protocol string `json:"protocol"` - - // Public port end - PublicPortEnd uint64 `json:"publicPortEnd"` - - // Public port start - PublicPortStart uint64 `json:"publicPortStart"` - - // Virtuel machine ID - VMID uint64 `json:"vmId"` -} - -// List port forwards -type ListPFWs []ItemPFW - -// Main information about affinity relations -type RecordAffinityRelations struct { - // Other node - OtherNode []interface{} `json:"otherNode"` - - // Other node indirect - OtherNodeIndirect []interface{} `json:"otherNodeIndirect"` - - // Other node indirect soft - OtherNodeIndirectSoft []interface{} `json:"otherNodeIndirectSoft"` - - // Other node soft - OtherNodeSoft []interface{} `json:"otherNodeSoft"` - - // Same node - SameNode []interface{} `json:"sameNode"` - - // Same node soft - SameNodeSoft []interface{} `json:"sameNodeSoft"` -} - -// Main information about attached network -type RecordNetAttach struct { - // Connection ID - ConnID uint64 `json:"connId"` - - // Connection type - ConnType string `json:"connType"` - - // Default GW - DefGW string `json:"defGw"` - - // FLIPGroup ID - FLIPGroupID uint64 `json:"flipgroupId"` - - // GUID - GUID string `json:"guid"` - - // IP address - IPAddress string `json:"ipAddress"` - - // Listen SSH - ListenSSH bool `json:"listenSsh"` - - // MAC - MAC string `json:"mac"` - - // Name - Name string `json:"name"` - - // Network ID - NetID uint64 `json:"netId"` - - // Network mask - NetMask uint64 `json:"netMask"` - - // Network type - NetType string `json:"netType"` - - // PCI slot - PCISlot uint64 `json:"pciSlot"` - - // QOS - QOS QOS `json:"qos"` - - // Target - Target string `json:"target"` - - // Type - Type string `json:"type"` - - // List VNF IDs - VNFs []uint64 `json:"vnfs"` -} - -// Detailed information about audit -type ItemAudit struct { - // Call - Call string `json:"call"` - - // Response time - ResponseTime float64 `json:"responsetime"` - - // Status code - StatusCode uint64 `json:"statuscode"` - - // Timestamp - Timestamp float64 `json:"timestamp"` - - // User - User string `json:"user"` -} - -// List Detailed audits -type ListAudits []ItemAudit - -// Short information about audit -type ItemShortAudit struct { - // Epoch - Epoch float64 `json:"epoch"` - - // Message - Message string `json:"message"` -} - -// List short audits -type ListShortAudits []ItemShortAudit - -// Main information about rule -type ItemRule struct { - // GUID - GUID string `json:"guid"` - - // Key - Key string `json:"key"` - - // Mode - Mode string `json:"mode"` - - // Policy - Policy string `json:"policy"` - - // Topology - Topology string `json:"topology"` - - // Value - Value string `json:"value"` -} - -// List rules -type ListRules []ItemRule - -// Detailed information about compute -type RecordCompute struct { - // Access Control List - ACL RecordACL `json:"ACL"` - - // Account ID - AccountID uint64 `json:"accountId"` - - // Account name - AccountName string `json:"accountName"` - - // Affinity label - AffinityLabel string `json:"affinityLabel"` - - // List affinity rules - AffinityRules ListRules `json:"affinityRules"` - - // Affinity weight - AffinityWeight uint64 `json:"affinityWeight"` - - // List anti affinity rules - AntiAffinityRules ListRules `json:"antiAffinityRules"` - - // Architecture - Architecture string `json:"arch"` - - // Boot order - BootOrder []string `json:"bootOrder"` - - // Boot disk size - BootDiskSize uint64 `json:"bootdiskSize"` - - // Clone reference - CloneReference uint64 `json:"cloneReference"` - - // List clone IDs - Clones []uint64 `json:"clones"` - - // Compute CI ID - ComputeCIID uint64 `json:"computeciId"` - - // Number of cores - CPU uint64 `json:"cpus"` - - // Created by - CreatedBy string `json:"createdBy"` - - // Created time - CreatedTime uint64 `json:"createdTime"` - - // Custom fields items - CustomFields map[string]interface{} `json:"customFields"` - - // Deleted by - DeletedBy string `json:"deletedBy"` - - // Deleted time - DeletedTime uint64 `json:"deletedTime"` - - // Description - Description string `json:"desc"` - - // Devices - Devices interface{} `json:"devices"` - - // List disks in compute - Disks ListComputeDisks `json:"disks"` - - // Driver - Driver string `json:"driver"` - - // Grid ID - GID uint64 `json:"gid"` - - // GUID - GUID uint64 `json:"guid"` - - // ID - ID uint64 `json:"id"` - - // Image ID - ImageID uint64 `json:"imageId"` - - // Image name - ImageName string `json:"imageName"` - - // List interfaces - Interfaces ListInterfaces `json:"interfaces"` - - // Lock status - LockStatus string `json:"lockStatus"` - - // Manager ID - ManagerID uint64 `json:"managerId"` - - // Manager type - ManagerType string `json:"managerType"` - - // Migration job - MigrationJob uint64 `json:"migrationjob"` - - // Milestones - Milestones uint64 `json:"milestones"` - - // Name - Name string `json:"name"` - - // Natable VINS ID - NatableVINSID uint64 `json:"natableVinsId"` - - // Natable VINS IP - NatableVINSIP string `json:"natableVinsIp"` - - // Natable VINS Name - NatableVINSName string `json:"natableVinsName"` - - // Natable VINS network - NatableVINSNetwork string `json:"natableVinsNetwork"` - - // Natable VINS network name - NatableVINSNetworkName string `json:"natableVinsNetworkName"` - - // List OS Users - OSUsers ListOSUser `json:"osUsers"` - - // Pinned or not - Pinned bool `json:"pinned"` - - // Number of RAM - RAM uint64 `json:"ram"` - - // Reference ID - ReferenceID string `json:"referenceId"` - - // Registered or not - Registered bool `json:"registered"` - - // Resource name - ResName string `json:"resName"` - - // Resource group ID - RGID uint64 `json:"rgId"` - - // Resource group name - RGName string `json:"rgName"` - - // List snapsets - SnapSets ListSnapSets `json:"snapSets"` - - // Stateless SepID - StatelessSepID uint64 `json:"statelessSepId"` - - // Stateless SepType - StatelessSepType string `json:"statelessSepType"` - - // Status - Status string `json:"status"` - - // Tags - Tags map[string]string `json:"tags"` - - // Tech status - TechStatus string `json:"techStatus"` - - // Updated by - UpdatedBy string `json:"updatedBy"` - - // Updated time - UpdatedTime uint64 `json:"updatedTime"` - - // User Managed or not - UserManaged bool `json:"userManaged"` - - // Userdata - Userdata interface{} `json:"userdata"` - - // vGPU IDs - VGPUs []uint64 `json:"vgpus"` - - // Virtual image ID - VirtualImageID uint64 `json:"virtualImageId"` - - // Virtual image name - VirtualImageName string `json:"virtualImageName"` -} - -// Main information about OS user -type ItemOSUser struct { - // GUID - GUID string `json:"guid"` - - // Login - Login string `json:"login"` - - // Password - Password string `json:"password"` - - // Public key - PubKey string `json:"pubkey"` -} - -// List OS users -type ListOSUser []ItemOSUser - -// Main information about snapsets -type ItemSnapSet struct { - // List disk IDs - Disks []uint64 `json:"disks"` - - // GUID - GUID string `json:"guid"` - - // Label - Label string `json:"label"` - - // Timestamp - Timestamp uint64 `json:"timestamp"` -} - -// List snapsets -type ListSnapSets []ItemSnapSet - -// Main information about VNF -type ItemVNFInterface struct { - // Connection ID - ConnID uint64 `json:"connId"` - - // Connection type - ConnType string `json:"connType"` - - // Default GW - DefGW string `json:"defGw"` - - // FLIPGroup ID - FLIPGroupID uint64 `json:"flipgroupId"` - - // GUID - GUID string `json:"guid"` - - // IP address - IPAddress string `json:"ipAddress"` - - // Listen SSH or not - ListenSSH bool `json:"listenSsh"` - - // MAC - MAC string `json:"mac"` - - // Name - Name string `json:"name"` - - // Network ID - NetID uint64 `json:"netId"` - - // Network mask - NetMask uint64 `json:"netMask"` - - // Network type - NetType string `json:"netType"` - - // PCI slot - PCISlot uint64 `json:"pciSlot"` - - // QOS - QOS QOS `json:"qos"` - - // Target - Target string `json:"target"` - - // Type - Type string `json:"type"` - - // List VNF IDs - VNFs []uint64 `json:"vnfs"` -} - -type QOS struct { - ERate uint64 `json:"eRate"` - GUID string `json:"guid"` - InBurst uint64 `json:"inBurst"` - InRate uint64 `json:"inRate"` -} - -// List VNF interfaces -type ListInterfaces []ItemVNFInterface - -// List compute disks -type ListComputeDisks []ItemComputeDisk - -// Main information about compute disk -type ItemComputeDisk struct { - // CKey - CKey string `json:"_ckey"` - - // Access Control List - ACL map[string]interface{} `json:"acl"` - - // Account ID - AccountID uint64 `json:"accountId"` - - // Boot partition - BootPartition uint64 `json:"bootPartition"` - - // Created time - CreatedTime uint64 `json:"createdTime"` - - // Deleted time - DeletedTime uint64 `json:"deletedTime"` - - // Description - Description string `json:"desc"` - - // Destruction time - DestructionTime uint64 `json:"destructionTime"` - - // Disk path - DiskPath string `json:"diskPath"` - - // Grid ID - GID uint64 `json:"gid"` - - // GUID - GUID uint64 `json:"guid"` - - // ID - ID uint64 `json:"id"` - - // Image ID - ImageID uint64 `json:"imageId"` - - // List image IDs - Images []uint64 `json:"images"` - - // IO tune - IOTune IOTune `json:"iotune"` - - // IQN - IQN string `json:"iqn"` - - // Login - Login string `json:"login"` - - // Milestones - Milestones uint64 `json:"milestones"` - - // Name - Name string `json:"name"` - - // Order - Order uint64 `json:"order"` - - // Params - Params string `json:"params"` - - // Parent ID - ParentID uint64 `json:"parentId"` - - // Password - Passwd string `json:"passwd"` - - // PCI slot - PCISlot uint64 `json:"pciSlot"` - - // Pool - Pool string `json:"pool"` - - // Present to - PresentTo []uint64 `json:"presentTo"` - - // Purge time - PurgeTime uint64 `json:"purgeTime"` - - // Reality device number - RealityDeviceNumber uint64 `json:"realityDeviceNumber"` - - // Resource ID - ResID string `json:"resId"` - - // Role - Role string `json:"role"` - - // SepID - SepID uint64 `json:"sepId"` - - // Shareable - Shareable bool `json:"shareable"` - - // Size max - SizeMax uint64 `json:"sizeMax"` - - //Size used - SizeUsed float64 `json:"sizeUsed"` - - // List extend snapshots - Snapshots SnapshotExtendList `json:"snapshots"` - - // Status - Status string `json:"status"` - - // Tech status - TechStatus string `json:"techStatus"` - - // Type - Type string `json:"type"` - - // Virtual machine ID - VMID uint64 `json:"vmid"` -} - -// Main information about snapshot extend -type SnapshotExtend struct { - // GUID - GUID string `json:"guid"` - - // Label - Label string `json:"label"` - - // Resource ID - ResID string `json:"resId"` - - // SnapSetGUID - SnapSetGUID string `json:"snapSetGuid"` - - // SnapSetTime - SnapSetTime uint64 `json:"snapSetTime"` - - // TimeStamp - TimeStamp uint64 `json:"timestamp"` -} - -// List Snapshot Extend -type SnapshotExtendList []SnapshotExtend - -// Main information about IO tune -type IOTune struct { - // ReadBytesSec - ReadBytesSec uint64 `json:"read_bytes_sec"` - - // ReadBytesSecMax - ReadBytesSecMax uint64 `json:"read_bytes_sec_max"` - - // ReadIOPSSec - ReadIOPSSec uint64 `json:"read_iops_sec"` - - // ReadIOPSSecMax - ReadIOPSSecMax uint64 `json:"read_iops_sec_max"` - - // SizeIOPSSec - SizeIOPSSec uint64 `json:"size_iops_sec"` - - // TotalBytesSec - TotalBytesSec uint64 `json:"total_bytes_sec"` - - // TotalBytesSecMax - TotalBytesSecMax uint64 `json:"total_bytes_sec_max"` - - // TotalIOPSSec - TotalIOPSSec uint64 `json:"total_iops_sec"` - - // TotalIOPSSecMax - TotalIOPSSecMax uint64 `json:"total_iops_sec_max"` - - // WriteBytesSec - WriteBytesSec uint64 `json:"write_bytes_sec"` - - // WriteBytesSecMax - WriteBytesSecMax uint64 `json:"write_bytes_sec_max"` - - // WriteIOPSSec - WriteIOPSSec uint64 `json:"write_iops_sec"` - - // WriteIOPSSecMax - WriteIOPSSecMax uint64 `json:"write_iops_sec_max"` -} - -// Main information about compute -type ItemCompute struct { - // Access Control List - ACL ListACL `json:"acl"` - - // Account ID - AccountID uint64 `json:"accountId"` - - // Account name - AccountName string `json:"accountName"` - - // Affinity label - AffinityLabel string `json:"affinityLabel"` - - // List affinity rules - AffinityRules ListRules `json:"affinityRules"` - - // Affinity weight - AffinityWeight uint64 `json:"affinityWeight"` - - // List anti affinity rules - AntiAffinityRules ListRules `json:"antiAffinityRules"` - - // Architecture - Architecture string `json:"arch"` - - // Boot order - BootOrder []string `json:"bootOrder"` - - // Boot disk size - BootDiskSize uint64 `json:"bootdiskSize"` - - // Clone reference - CloneReference uint64 `json:"cloneReference"` - - // List clone IDs - Clones []uint64 `json:"clones"` - - // Compute CI ID - ComputeCIID uint64 `json:"computeciId"` - - // Number of cores - CPU uint64 `json:"cpus"` - - // Created by - CreatedBy string `json:"createdBy"` - - // Created time - CreatedTime uint64 `json:"createdTime"` - - // Custom fields list - CustomFields map[string]interface{} `json:"customFields"` - - // Deleted by - DeletedBy string `json:"deletedBy"` - - // Deleted time - DeletedTime uint64 `json:"deletedTime"` - - // Description - Description string `json:"desc"` - - // Devices - Devices interface{} `json:"devices"` - - // List disk items - Disks []InfoDisk `json:"disks"` - - // Driver - Driver string `json:"driver"` - - // Grid ID - GID uint64 `json:"gid"` - - // GUID - GUID uint64 `json:"guid"` - - // ID - ID uint64 `json:"id"` - - // Image ID - ImageID uint64 `json:"imageId"` - - // List interfaces - Interfaces ListInterfaces `json:"interfaces"` - - // Lock status - LockStatus string `json:"lockStatus"` - - // Manager ID - ManagerID uint64 `json:"managerId"` - - // Manager type - ManagerType string `json:"managerType"` - - // Migration job - MigrationJob uint64 `json:"migrationjob"` - - // Milestones - Milestones uint64 `json:"milestones"` - - // Name - Name string `json:"name"` - - // Pinned or not - Pinned bool `json:"pinned"` - - // Number of RAM - RAM uint64 `json:"ram"` - - // Reference ID - ReferenceID string `json:"referenceId"` - - // Registered - Registered bool `json:"registered"` - - // Resource name - ResName string `json:"resName"` - - // Resource group ID - RGID uint64 `json:"rgId"` - - // Resource group name - RGName string `json:"rgName"` - - // List snapsets - SnapSets ListSnapSets `json:"snapSets"` - - // Stateless SepID - StatelessSepID uint64 `json:"statelessSepId"` - - // Stateless SepType - StatelessSepType string `json:"statelessSepType"` - - // Status - Status string `json:"status"` - - // Tags - Tags map[string]string `json:"tags"` - - // Tech status - TechStatus string `json:"techStatus"` - - // Total disk size - TotalDiskSize uint64 `json:"totalDisksSize"` - - // Updated by - UpdatedBy string `json:"updatedBy"` - - // Updated time - UpdatedTime uint64 `json:"updatedTime"` - - // User Managed or not - UserManaged bool `json:"userManaged"` - - // List vGPU IDs - VGPUs []uint64 `json:"vgpus"` - - // VINS connected - VINSConnected uint64 `json:"vinsConnected"` - - // Virtual image ID - VirtualImageID uint64 `json:"virtualImageId"` -} - -// Information Disk -type InfoDisk struct { - // ID - ID uint64 `json:"id"` - - // PCISlot - PCISlot uint64 `json:"pciSlot"` -} - -// List information about computes -type ListComputes []ItemCompute diff --git a/internal/service/cloudapi/kvmvm/osusers_subresource.go b/internal/service/cloudapi/kvmvm/osusers_subresource.go index 96b7828..49e3f67 100644 --- a/internal/service/cloudapi/kvmvm/osusers_subresource.go +++ b/internal/service/cloudapi/kvmvm/osusers_subresource.go @@ -34,11 +34,12 @@ package kvmvm import ( log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func parseOsUsers(logins ListOSUser) []interface{} { +func parseOsUsers(logins compute.ListOSUser) []interface{} { var result = make([]interface{}, len(logins)) for index, value := range logins { diff --git a/internal/service/cloudapi/kvmvm/resource_check_input_values.go b/internal/service/cloudapi/kvmvm/resource_check_input_values.go index a0377f2..3280dbd 100644 --- a/internal/service/cloudapi/kvmvm/resource_check_input_values.go +++ b/internal/service/cloudapi/kvmvm/resource_check_input_values.go @@ -34,89 +34,89 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func existRgID(ctx context.Context, d *schema.ResourceData, m interface{}) bool { +func existRgID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - rgList := []struct { - ID int `json:"id"` - }{} - - rgListAPI := "/restmachine/cloudapi/rg/list" - urlValues.Add("includedeleted", "false") - rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues) - if err != nil { - return false + rgId := uint64(d.Get("rg_id").(int)) + req := rg.ListRequest{ + IncludeDeleted: false, } - err = json.Unmarshal([]byte(rgListRaw), &rgList) + + rgList, err := c.CloudAPI().RG().List(ctx, req) if err != nil { - return false - } - rgId := d.Get("rg_id").(int) - for _, rg := range rgList { - if rg.ID == rgId { - return true - } + return false, err } - return false + + return len(rgList.FilterByID(rgId)) != 0, nil } -func existImageId(ctx context.Context, d *schema.ResourceData, m interface{}) bool { +func existImageId(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - imageList := []struct { - ID int `json:"id"` - }{} - imageListAPI := "/restmachine/cloudapi/image/list" - imageListRaw, err := c.DecortAPICall(ctx, "POST", imageListAPI, urlValues) - if err != nil { - return false - } - err = json.Unmarshal([]byte(imageListRaw), &imageList) + imageId := uint64(d.Get("image_id").(int)) + req := image.ListRequest{} + + imageList, err := c.CloudAPI().Image().List(ctx, req) if err != nil { - return false + return false, err } - imageId := d.Get("image_id").(int) - for _, image := range imageList { - if image.ID == imageId { + + return len(imageList.FilterByID(imageId)) != 0, nil +} + +func existVinsIdInList(vinsId uint64, vinsList vins.ListVINS) bool { + for _, vins := range vinsList { + if vinsId == vins.ID { return true } } + return false } -func existVinsIdInList(vinsId int, vinsList []struct { - ID int `json:"id"` -}) bool { - for _, vins := range vinsList { - if vinsId == vins.ID { +func existExtNetIdInList(extId uint64, extList extnet.ListExtNets) bool { + for _, ext := range extList { + if extId == ext.ID { return true } } + return false } func existVinsId(ctx context.Context, d *schema.ResourceData, m interface{}) (int, bool) { - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - vinsListAPI := "/restmachine/cloudapi/vins/list" - urlValues.Add("includeDeleted", "false") - vinsList := []struct { - ID int `json:"id"` - }{} - vinsListRaw, err := c.DecortAPICall(ctx, "POST", vinsListAPI, urlValues) + req := vins.ListRequest{IncludeDeleted: false} + + vinsList, err := c.CloudAPI().VINS().List(ctx, req) if err != nil { return 0, false } - err = json.Unmarshal([]byte(vinsListRaw), &vinsList) + + networks := d.Get("network").(*schema.Set).List() + + for _, networkInterface := range networks { + networkItem := networkInterface.(map[string]interface{}) + if !existVinsIdInList(uint64(networkItem["net_id"].(int)), vinsList) { + return networkItem["net_id"].(int), false + } + } + + return 0, true +} + +func existExtNetId(ctx context.Context, d *schema.ResourceData, m interface{}) (int, bool) { + c := m.(*controller.ControllerCfg) + req := extnet.ListRequest{} + + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) if err != nil { return 0, false } @@ -124,11 +124,11 @@ func existVinsId(ctx context.Context, d *schema.ResourceData, m interface{}) (in networks := d.Get("network").(*schema.Set).List() for _, networkInterface := range networks { - networkItem := networkInterface.(map[string]interface{}) - if !existVinsIdInList(networkItem["net_id"].(int), vinsList) { + if !existExtNetIdInList(uint64(networkItem["net_id"].(int)), extNetList) { return networkItem["net_id"].(int), false } } + return 0, true } diff --git a/internal/service/cloudapi/kvmvm/resource_compute.go b/internal/service/cloudapi/kvmvm/resource_compute.go index 80cdcef..e6372e5 100644 --- a/internal/service/cloudapi/kvmvm/resource_compute.go +++ b/internal/service/cloudapi/kvmvm/resource_compute.go @@ -34,11 +34,12 @@ package kvmvm import ( "context" - "fmt" - "net/url" "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmppc" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" @@ -51,138 +52,162 @@ import ( ) func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - // we assume all mandatory parameters it takes to create a comptue instance are properly - // specified - we rely on schema "Required" attributes to let Terraform validate them for us - log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + createReqX86 := kvmx86.CreateRequest{} + createReqPPC := kvmppc.CreateRequest{} - if !existRgID(ctx, d, m) { - return diag.Errorf("resourceComputeCreate: can't create Compute bacause rgID %d not allowed or does not exist", d.Get("rg_id").(int)) + hasRG, err := existRgID(ctx, d, m) + if err != nil { + return diag.FromErr(err) } - if !existImageId(ctx, d, m) { - return diag.Errorf("resourceComputeCreate: can't create Compute bacause imageID %d not allowed or does not exist", d.Get("image_id").(int)) + if !hasRG { + return diag.Errorf("resourceComputeCreate: can't create Compute because rgID %d is not allowed or does not exist", d.Get("rg_id").(int)) } - if _, ok := d.GetOk("network"); ok { - if vinsId, ok := existVinsId(ctx, d, m); !ok { - return diag.Errorf("resourceResgroupCreate: can't create RG bacause vins ID %d not allowed or does not exist", vinsId) - } + hasImage, err := existImageId(ctx, d, m) + if err != nil { + return diag.FromErr(err) } - // create basic Compute (i.e. without extra disks and network connections - those will be attached - // by subsequent individual API calls). - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("cpu", strconv.Itoa(d.Get("cpu").(int))) - urlValues.Add("ram", strconv.Itoa(d.Get("ram").(int))) - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - urlValues.Add("netType", "NONE") - urlValues.Add("start", "0") // at the 1st step create compute in a stopped state + if !hasImage { + return diag.Errorf("resourceComputeCreate: can't create Compute because imageID %d is not allowed or does not exist", d.Get("image_id").(int)) + } + + if network, ok := d.GetOk("network"); ok { + networkData := network.(*schema.Set).List()[0].(map[string]interface{}) + if networkData["net_type"].(string) == "VINS" { + if vinsId, ok := existVinsId(ctx, d, m); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because vins ID %d is not allowed or does not exist", vinsId) + } + } else if networkData["net_type"].(string) == "EXTNET" { + if extNetId, ok := existExtNetId(ctx, d, m); !ok { + return diag.Errorf("resourceComputeCreate: can't create compute because extnet ID %d is not allowed or does not exist", extNetId) + } + } + } argVal, ok := d.GetOk("description") if ok { - urlValues.Add("desc", argVal.(string)) + createReqPPC.Description = argVal.(string) + createReqX86.Description = argVal.(string) } if sepID, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sepId", strconv.Itoa(sepID.(int))) + createReqPPC.SEPID = uint64(sepID.(int)) + createReqX86.SepID = uint64(sepID.(int)) } if pool, ok := d.GetOk("pool"); ok { - urlValues.Add("pool", pool.(string)) + createReqPPC.Pool = pool.(string) + createReqX86.Pool = pool.(string) } if ipaType, ok := d.GetOk("ipa_type"); ok { - urlValues.Add("ipaType", ipaType.(string)) + createReqPPC.IPAType = ipaType.(string) + createReqX86.IPAType = ipaType.(string) } if bootSize, ok := d.GetOk("boot_disk_size"); ok { - urlValues.Add("bootDisk", fmt.Sprintf("%d", bootSize.(int))) + createReqPPC.BootDisk = uint64(bootSize.(int)) + createReqX86.BootDisk = uint64(bootSize.(int)) } if IS, ok := d.GetOk("is"); ok { - urlValues.Add("IS", IS.(string)) + createReqPPC.IS = IS.(string) + createReqX86.IS = IS.(string) } if networks, ok := d.GetOk("network"); ok { if networks.(*schema.Set).Len() > 0 { ns := networks.(*schema.Set).List() defaultNetwork := ns[0].(map[string]interface{}) - urlValues.Set("netType", defaultNetwork["net_type"].(string)) - urlValues.Add("netId", fmt.Sprintf("%d", defaultNetwork["net_id"].(int))) + + createReqPPC.NetType = defaultNetwork["net_type"].(string) + createReqPPC.NetID = uint64(defaultNetwork["net_id"].(int)) + + createReqX86.NetType = defaultNetwork["net_type"].(string) + createReqX86.NetID = uint64(defaultNetwork["net_id"].(int)) + ipaddr, ipSet := defaultNetwork["ip_address"] // "ip_address" key is optional if ipSet { - urlValues.Add("ipAddr", ipaddr.(string)) + createReqPPC.IPAddr = ipaddr.(string) + createReqX86.IPAddr = ipaddr.(string) } } } - /* - sshKeysVal, sshKeysSet := d.GetOk("ssh_keys") - if sshKeysSet { - // process SSH Key settings and set API values accordingly - log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)") - urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{}))) + argVal, ok = d.GetOk("cloud_init") + if ok { + userdata := argVal.(string) + if userdata != "" && userdata != "applied" { + createReqPPC.Userdata = userdata + createReqX86.Userdata = userdata } - */ + } - computeCreateAPI := KvmX86CreateAPI + var computeId uint64 driver := d.Get("driver").(string) if driver == "KVM_PPC" { - computeCreateAPI = KvmPPCCreateAPI + createReqPPC.RGID = uint64(d.Get("rg_id").(int)) + createReqPPC.Name = d.Get("name").(string) + createReqPPC.CPU = uint64(d.Get("cpu").(int)) + createReqPPC.RAM = uint64(d.Get("ram").(int)) + createReqPPC.ImageID = uint64(d.Get("image_id").(int)) + log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC") - } else { // note that we do not validate arch value for explicit "KVM_X86" here - log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86") - } + apiResp, err := c.CloudAPI().KVMPPC().Create(ctx, createReqPPC) + if err != nil { + return diag.FromErr(err) + } - argVal, ok = d.GetOk("cloud_init") - if ok { - // userdata must not be empty string and must not be a reserved keyword "applied" - userdata := argVal.(string) - if userdata != "" && userdata != "applied" { - urlValues.Add("userdata", userdata) + d.SetId(strconv.FormatUint(apiResp, 10)) + computeId = apiResp + } else { + createReqX86.RGID = uint64(d.Get("rg_id").(int)) + createReqX86.Name = d.Get("name").(string) + createReqX86.CPU = uint64(d.Get("cpu").(int)) + createReqX86.RAM = uint64(d.Get("ram").(int)) + createReqX86.ImageID = uint64(d.Get("image_id").(int)) + + log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86") + apiResp, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86) + if err != nil { + return diag.FromErr(err) } - } - apiResp, err := c.DecortAPICall(ctx, "POST", computeCreateAPI, urlValues) - if err != nil { - return diag.FromErr(err) + d.SetId(strconv.FormatUint(apiResp, 10)) + computeId = apiResp } - urlValues = &url.Values{} - // Compute create API returns ID of the new Compute instance on success - - d.SetId(apiResp) // update ID of the resource to tell Terraform that the resource exists, albeit partially - compId, _ := strconv.Atoi(apiResp) warnings := dc.Warnings{} cleanup := false defer func() { if cleanup { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("permanently", "1") - urlValues.Add("detachDisks", "1") + req := compute.DeleteRequest{ + ComputeID: computeId, + Permanently: true, + DetachDisks: true, + } - if _, err := c.DecortAPICall(ctx, "POST", ComputeDeleteAPI, urlValues); err != nil { + if _, err := c.CloudAPI().Compute().Delete(ctx, req); err != nil { log.Errorf("resourceComputeCreate: could not delete compute after failed creation: %v", err) } + d.SetId("") - urlValues = &url.Values{} } }() - log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string)) + log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", computeId, d.Get("name").(string)) argVal, ok = d.GetOk("extra_disks") if ok && argVal.(*schema.Set).Len() > 0 { log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len()) - err = utilityComputeExtraDisksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute + err = utilityComputeExtraDisksConfigure(ctx, d, m, false) if err != nil { - log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", compId, err) + log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", computeId, err) cleanup = true return diag.FromErr(err) } @@ -192,7 +217,7 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len()) err = utilityComputeNetworksConfigure(ctx, d, m, false, true) if err != nil { - log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err) + log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", computeId, err) cleanup = true return diag.FromErr(err) } @@ -201,133 +226,137 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf // Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface), // now we need to start it before we report the sequence complete if d.Get("started").(bool) { - reqValues := &url.Values{} - reqValues.Add("computeId", fmt.Sprintf("%d", compId)) - log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId) - if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, reqValues); err != nil { + req := compute.StartRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId) + if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil { warnings.Add(err) } } if enabled, ok := d.GetOk("enabled"); ok { - api := ComputeDisableAPI if enabled.(bool) { - api = ComputeEnableAPI - } - urlValues := &url.Values{} - urlValues.Add("computeId", fmt.Sprintf("%d", compId)) - log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", compId, enabled) - if _, err := c.DecortAPICall(ctx, "POST", api, urlValues); err != nil { - warnings.Add(err) + req := compute.EnableRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", computeId, enabled) + if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil { + warnings.Add(err) + } + } else { + req := compute.DisableRequest{ComputeID: computeId} + log.Debugf("resourceComputeCreate: enable=%t Compute ID %d after completing its resource configuration", computeId, enabled) + if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil { + warnings.Add(err) + } } - } if !cleanup { if affinityLabel, ok := d.GetOk("affinity_label"); ok { - affinityLabel := affinityLabel.(string) - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("affinityLabel", affinityLabel) - _, err := c.DecortAPICall(ctx, "POST", ComputeAffinityLabelSetAPI, urlValues) + req := compute.AffinityLabelSetRequest{ + ComputeID: computeId, + AffinityLabel: affinityLabel.(string), + } + + _, err := c.CloudAPI().Compute().AffinityLabelSet(ctx, req) if err != nil { warnings.Add(err) } - urlValues = &url.Values{} } if disks, ok := d.GetOk("disks"); ok { - log.Debugf("resourceComputeCreate: Create disks on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create disks on ComputeID: %d", computeId) addedDisks := disks.([]interface{}) if len(addedDisks) > 0 { for _, disk := range addedDisks { diskConv := disk.(map[string]interface{}) + req := compute.DiskAddRequest{ + ComputeID: computeId, + DiskName: diskConv["disk_name"].(string), + Size: uint64(diskConv["size"].(int)), + SepID: uint64(diskConv["sep_id"].(int)), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskName", diskConv["disk_name"].(string)) - urlValues.Add("size", strconv.Itoa(diskConv["size"].(int))) if diskConv["disk_type"].(string) != "" { - urlValues.Add("diskType", diskConv["disk_type"].(string)) - } - if diskConv["sep_id"].(int) != 0 { - urlValues.Add("sepId", strconv.Itoa(diskConv["sep_id"].(int))) + req.DiskType = diskConv["disk_type"].(string) } if diskConv["pool"].(string) != "" { - urlValues.Add("pool", diskConv["pool"].(string)) + req.Pool = diskConv["pool"].(string) } if diskConv["desc"].(string) != "" { - urlValues.Add("desc", diskConv["desc"].(string)) + req.Description = diskConv["desc"].(string) } if diskConv["image_id"].(int) != 0 { - urlValues.Add("imageId", strconv.Itoa(diskConv["image_id"].(int))) + req.ImageID = uint64(diskConv["image_id"].(int)) } - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskAddAPI, urlValues) + + _, err := c.CloudAPI().Compute().DiskAdd(ctx, req) if err != nil { cleanup = true return diag.FromErr(err) } - urlValues = &url.Values{} } } } if ars, ok := d.GetOk("affinity_rules"); ok { - log.Debugf("resourceComputeCreate: Create affinity rules on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create affinity rules on ComputeID: %d", computeId) addedAR := ars.([]interface{}) if len(addedAR) > 0 { for _, ar := range addedAR { arConv := ar.(map[string]interface{}) + req := compute.AffinityRuleAddRequest{ + ComputeID: computeId, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("topology", arConv["topology"].(string)) - urlValues.Add("policy", arConv["policy"].(string)) - urlValues.Add("mode", arConv["mode"].(string)) - urlValues.Add("key", arConv["key"].(string)) - urlValues.Add("value", arConv["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeAffinityRuleAddAPI, urlValues) + _, err := c.CloudAPI().Compute().AffinityRuleAdd(ctx, req) if err != nil { warnings.Add(err) } - urlValues = &url.Values{} } } } if ars, ok := d.GetOk("anti_affinity_rules"); ok { - log.Debugf("resourceComputeCreate: Create anti affinity rules on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create anti affinity rules on ComputeID: %d", computeId) addedAR := ars.([]interface{}) if len(addedAR) > 0 { for _, ar := range addedAR { arConv := ar.(map[string]interface{}) + req := compute.AntiAffinityRuleAddRequest{ + ComputeID: computeId, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("topology", arConv["topology"].(string)) - urlValues.Add("policy", arConv["policy"].(string)) - urlValues.Add("mode", arConv["mode"].(string)) - urlValues.Add("key", arConv["key"].(string)) - urlValues.Add("value", arConv["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeAntiAffinityRuleAddAPI, urlValues) + _, err := c.CloudAPI().Compute().AntiAffinityRuleAdd(ctx, req) if err != nil { warnings.Add(err) } - urlValues = &url.Values{} } } } } if tags, ok := d.GetOk("tags"); ok { - log.Debugf("resourceComputeCreate: Create tags on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create tags on ComputeID: %d", computeId) addedTags := tags.(*schema.Set).List() if len(addedTags) > 0 { for _, tagInterface := range addedTags { - urlValues = &url.Values{} tagItem := tagInterface.(map[string]interface{}) + req := compute.TagAddRequest{ + ComputeID: computeId, + Key: tagItem["key"].(string), + Value: tagItem["value"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("key", tagItem["key"].(string)) - urlValues.Add("value", tagItem["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeTagAddAPI, urlValues) + _, err := c.CloudAPI().Compute().TagAdd(ctx, req) if err != nil { warnings.Add(err) } @@ -336,19 +365,20 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf } if pfws, ok := d.GetOk("port_forwarding"); ok { - log.Debugf("resourceComputeCreate: Create port farwarding on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create port farwarding on ComputeID: %d", computeId) addedPfws := pfws.(*schema.Set).List() if len(addedPfws) > 0 { for _, pfwInterface := range addedPfws { - urlValues = &url.Values{} pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWAddRequest{ + ComputeID: computeId, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + PublicPortEnd: uint64(pfwItem["public_port_end"].(int)), + LocalBasePort: uint64(pfwItem["local_port"].(int)), + Proto: pfwItem["proto"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("publicPortStart", strconv.Itoa(pfwItem["public_port_start"].(int))) - urlValues.Add("publicPortEnd", strconv.Itoa(pfwItem["public_port_end"].(int))) - urlValues.Add("localBasePort", strconv.Itoa(pfwItem["local_port"].(int))) - urlValues.Add("proto", pfwItem["proto"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputePfwAddAPI, urlValues) + _, err := c.CloudAPI().Compute().PFWAdd(ctx, req) if err != nil { warnings.Add(err) } @@ -356,17 +386,18 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf } } if userAcess, ok := d.GetOk("user_access"); ok { - log.Debugf("resourceComputeCreate: Create user access on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create user access on ComputeID: %d", computeId) usersAcess := userAcess.(*schema.Set).List() if len(usersAcess) > 0 { for _, userAcessInterface := range usersAcess { - urlValues = &url.Values{} userAccessItem := userAcessInterface.(map[string]interface{}) + req := compute.UserGrantRequest{ + ComputeID: computeId, + Username: userAccessItem["username"].(string), + AccessType: userAccessItem["access_type"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("userName", userAccessItem["username"].(string)) - urlValues.Add("accesstype", userAccessItem["access_type"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeUserGrantAPI, urlValues) + _, err := c.CloudAPI().Compute().UserGrant(ctx, req) if err != nil { warnings.Add(err) } @@ -375,16 +406,17 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf } if snapshotList, ok := d.GetOk("snapshot"); ok { - log.Debugf("resourceComputeCreate: Create snapshot on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create snapshot on ComputeID: %d", computeId) snapshots := snapshotList.(*schema.Set).List() if len(snapshots) > 0 { for _, snapshotInterface := range snapshots { - urlValues = &url.Values{} snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotCreateRequest{ + ComputeID: computeId, + Label: snapshotItem["label"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("userName", snapshotItem["label"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeSnapshotCreateAPI, urlValues) + _, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req) if err != nil { warnings.Add(err) } @@ -393,15 +425,16 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf } if cdtList, ok := d.GetOk("cd"); ok { - log.Debugf("resourceComputeCreate: Create cd on ComputeID: %d", compId) + log.Debugf("resourceComputeCreate: Create cd on ComputeID: %d", computeId) cds := cdtList.(*schema.Set).List() if len(cds) > 0 { - urlValues = &url.Values{} snapshotItem := cds[0].(map[string]interface{}) + req := compute.CDInsertRequest{ + ComputeID: computeId, + CDROMID: uint64(snapshotItem["cdrom_id"].(int)), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("cdromId", strconv.Itoa(snapshotItem["cdrom_id"].(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeCdInsertAPI, urlValues) + _, err := c.CloudAPI().Compute().CDInsert(ctx, req) if err != nil { warnings.Add(err) } @@ -409,24 +442,26 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf } if d.Get("pin_to_stack").(bool) == true { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", ComputePinToStackAPI, urlValues) + req := compute.PinToStackRequest{ + ComputeID: computeId, + } + _, err := c.CloudAPI().Compute().PinToStack(ctx, req) if err != nil { warnings.Add(err) } } if d.Get("pause").(bool) == true { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", ComputePauseAPI, urlValues) + req := compute.PauseRequest{ + ComputeID: computeId, + } + _, err := c.CloudAPI().Compute().Pause(ctx, req) if err != nil { warnings.Add(err) } } - log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", compId, d.Get("name").(string)) + log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", computeId, d.Get("name").(string)) // We may reuse dataSourceComputeRead here as we maintain similarity // between Compute resource and Compute data source schemas @@ -442,22 +477,24 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac c := m.(*controller.ControllerCfg) - compute, err := utilityComputeCheckPresence(ctx, d, m) + computeRec, err := utilityComputeCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } hasChanged := false - switch compute.Status { + switch computeRec.Status { case status.Deleted: - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", ComputeRestoreAPI, urlValues) + restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID} + enableReq := compute.EnableRequest{ComputeID: computeRec.ID} + + _, err := c.CloudAPI().Compute().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", ComputeEnableAPI, urlValues) + + _, err = c.CloudAPI().Compute().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } @@ -467,24 +504,24 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac d.SetId("") return resourceComputeCreate(ctx, d, m) case status.Disabled: - log.Debugf("The compute is in status: %s, troubles may occur with update. Please, enable compute first.", compute.Status) + log.Debugf("The compute is in status: %s, troubles may occur with update. Please, enable compute first.", computeRec.Status) case status.Redeploying: case status.Deleting: case status.Destroying: - return diag.Errorf("The compute is in progress with status: %s", compute.Status) + return diag.Errorf("The compute is in progress with status: %s", computeRec.Status) case status.Modeled: - return diag.Errorf("The compute is in status: %s, please, contact support for more information", compute.Status) + return diag.Errorf("The compute is in status: %s, please, contact support for more information", computeRec.Status) } if hasChanged { - compute, err = utilityComputeCheckPresence(ctx, d, m) + computeRec, err = utilityComputeCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } } - if err = flattenCompute(d, compute); err != nil { + if err = flattenCompute(d, computeRec); err != nil { return diag.FromErr(err) } @@ -499,132 +536,154 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf d.Id(), d.Get("name").(string), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - if !existRgID(ctx, d, m) { + hasRG, err := existRgID(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !hasRG { return diag.Errorf("resourceComputeUpdate: can't update Compute bacause rgID %d not allowed or does not exist", d.Get("rg_id").(int)) } - if !existImageId(ctx, d, m) { + hasImage, err := existImageId(ctx, d, m) + if err != nil { + return diag.FromErr(err) + } + + if !hasImage { return diag.Errorf("resourceComputeUpdate: can't update Compute bacause imageID %d not allowed or does not exist", d.Get("image_id").(int)) } - if _, ok := d.GetOk("network"); ok { - if vinsId, ok := existVinsId(ctx, d, m); !ok { - return diag.Errorf("resourceResgroupUpdate: can't update RG bacause vinsID %d not allowed or does not exist", vinsId) + if network, ok := d.GetOk("network"); ok { + networkData := network.(*schema.Set).List()[0].(map[string]interface{}) + if networkData["net_type"].(string) == "VINS" { + if vinsId, ok := existVinsId(ctx, d, m); !ok { + return diag.Errorf("resourceComputeUpdate: can't create update because vins ID %d is not allowed or does not exist", vinsId) + } + } else if networkData["net_type"].(string) == "EXTNET" { + if extNetId, ok := existExtNetId(ctx, d, m); !ok { + return diag.Errorf("resourceComputeUpdate: can't create update because extnet ID %d is not allowed or does not exist", extNetId) + } } } - compute, err := utilityComputeCheckPresence(ctx, d, m) + computeRec, err := utilityComputeCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } if d.HasChange("enabled") { - enabled := d.Get("enabled") - api := ComputeDisableAPI - if enabled.(bool) { - api = ComputeEnableAPI + enabled := d.Get("enabled").(bool) + if enabled { + req := compute.EnableRequest{ + ComputeID: computeRec.ID, + } + + if _, err := c.CloudAPI().Compute().Enable(ctx, req); err != nil { + return diag.FromErr(err) + } + } else { + req := compute.DisableRequest{ + ComputeID: computeRec.ID, + } + + if _, err := c.CloudAPI().Compute().Disable(ctx, req); err != nil { + return diag.FromErr(err) + } } - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) log.Debugf("resourceComputeUpdate: enable=%t Compute ID %s after completing its resource configuration", d.Id(), enabled) - if _, err := c.DecortAPICall(ctx, "POST", api, urlValues); err != nil { - return diag.FromErr(err) - } } // check compute statuses - switch compute.Status { + switch computeRec.Status { case status.Deleted: - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", ComputeRestoreAPI, urlValues) + restoreReq := compute.RestoreRequest{ComputeID: computeRec.ID} + enableReq := compute.EnableRequest{ComputeID: computeRec.ID} + + _, err := c.CloudAPI().Compute().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", ComputeEnableAPI, urlValues) + + _, err = c.CloudAPI().Compute().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } + case status.Destroyed: d.SetId("") return resourceComputeCreate(ctx, d, m) case status.Disabled: - log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", compute.Status) + log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", computeRec.Status) case status.Redeploying: case status.Deleting: case status.Destroying: - return diag.Errorf("The compute is in progress with status: %s", compute.Status) + return diag.Errorf("The compute is in progress with status: %s", computeRec.Status) case status.Modeled: - return diag.Errorf("The compute is in status: %s, please, contant the support for more information", compute.Status) + return diag.Errorf("The compute is in status: %s, please, contant the support for more information", computeRec.Status) } - /* - 1. Resize CPU/RAM - 2. Resize (grow) boot disk - 3. Update extra disks - 4. Update networks - 5. Start/stop - */ - - // 1. Resize CPU/RAM - urlValues = &url.Values{} doUpdate := false - urlValues.Add("computeId", d.Id()) + resizeReq := compute.ResizeRequest{ + ComputeID: computeRec.ID, + Force: true, + } oldCpu, newCpu := d.GetChange("cpu") if oldCpu.(int) != newCpu.(int) { - urlValues.Add("cpu", fmt.Sprintf("%d", newCpu.(int))) + resizeReq.CPU = uint64(newCpu.(int)) doUpdate = true } else { - urlValues.Add("cpu", "0") // no change to CPU allocation + resizeReq.CPU = 0 } oldRam, newRam := d.GetChange("ram") if oldRam.(int) != newRam.(int) { - urlValues.Add("ram", fmt.Sprintf("%d", newRam.(int))) + resizeReq.RAM = uint64(newRam.(int)) doUpdate = true } else { - urlValues.Add("ram", "0") + resizeReq.RAM = 0 } if doUpdate { log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d", oldCpu.(int), newCpu.(int), oldRam.(int), newRam.(int)) - urlValues.Add("force", "true") - _, err := c.DecortAPICall(ctx, "POST", ComputeResizeAPI, urlValues) + _, err := c.CloudAPI().Compute().Resize(ctx, resizeReq) if err != nil { return diag.FromErr(err) } } - // 2. Resize (grow) Boot disk oldSize, newSize := d.GetChange("boot_disk_size") if oldSize.(int) < newSize.(int) { - urlValues := &url.Values{} + req := compute.DiskResizeRequest{ComputeID: computeRec.ID} if diskId, ok := d.GetOk("boot_disk_id"); ok { - urlValues.Add("diskId", strconv.Itoa(diskId.(int))) + req.DiskID = uint64(diskId.(int)) + } else { bootDisk, err := utilityComputeBootDiskCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - urlValues.Add("diskId", strconv.FormatUint(bootDisk.ID, 10)) + + req.DiskID = bootDisk.ID } - urlValues.Add("size", strconv.Itoa(newSize.(int))) + req.Size = uint64(newSize.(int)) + log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d", d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int)) - _, err := c.DecortAPICall(ctx, "POST", DisksResizeAPI, urlValues) + + _, err := c.CloudAPI().Compute().DiskResize(ctx, req) if err != nil { return diag.FromErr(err) } + } else if oldSize.(int) > newSize.(int) { log.Warnf("resourceComputeUpdate: compute ID %s - shrinking boot disk is not allowed", d.Id()) } - // 3. Calculate and apply changes to data disks if d.HasChange("extra_disks") { err := utilityComputeExtraDisksConfigure(ctx, d, m, true) // pass do_delta = true to apply changes, if any if err != nil { @@ -632,23 +691,23 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf } } - // 4. Calculate and apply changes to network connections err = utilityComputeNetworksConfigure(ctx, d, m, true, false) // pass do_delta = true to apply changes, if any if err != nil { return diag.FromErr(err) } if d.HasChange("description") || d.HasChange("name") { - updateParams := &url.Values{} - updateParams.Add("computeId", d.Id()) - updateParams.Add("name", d.Get("name").(string)) - updateParams.Add("desc", d.Get("description").(string)) - if _, err := c.DecortAPICall(ctx, "POST", ComputeUpdateAPI, updateParams); err != nil { + req := compute.UpdateRequest{ + ComputeID: computeRec.ID, + Name: d.Get("name").(string), + Description: d.Get("desc").(string), + } + + if _, err := c.CloudAPI().Compute().Update(ctx, req); err != nil { return diag.FromErr(err) } } - urlValues = &url.Values{} if d.HasChange("disks") { deletedDisks := make([]interface{}, 0) addedDisks := make([]interface{}, 0) @@ -675,36 +734,41 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf } if len(deletedDisks) > 0 { - urlValues.Add("computeId", d.Id()) - urlValues.Add("force", "false") - _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, urlValues) + stopReq := compute.StopRequest{ + ComputeID: computeRec.ID, + Force: false, + } + + _, err := c.CloudAPI().Compute().Stop(ctx, stopReq) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} for _, disk := range deletedDisks { diskConv := disk.(map[string]interface{}) if diskConv["disk_name"].(string) == "bootdisk" { continue } - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskId", strconv.Itoa(diskConv["disk_id"].(int))) - urlValues.Add("permanently", strconv.FormatBool(diskConv["permanently"].(bool))) - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskDeleteAPI, urlValues) + + req := compute.DiskDelRequest{ + ComputeID: computeRec.ID, + DiskID: uint64(diskConv["disk_id"].(int)), + Permanently: diskConv["permanently"].(bool), + } + + _, err := c.CloudAPI().Compute().DiskDel(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } - urlValues.Add("computeId", d.Id()) - urlValues.Add("altBootId", "0") - _, err = c.DecortAPICall(ctx, "POST", ComputeStartAPI, urlValues) + req := compute.StartRequest{ + ComputeID: computeRec.ID, + AltBootID: 0, + } + _, err = c.CloudAPI().Compute().Start(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if len(addedDisks) > 0 { @@ -713,30 +777,29 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf if diskConv["disk_name"].(string) == "bootdisk" { continue } - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskName", diskConv["disk_name"].(string)) - urlValues.Add("size", strconv.Itoa(diskConv["size"].(int))) - if diskConv["disk_type"].(string) != "" { - urlValues.Add("diskType", diskConv["disk_type"].(string)) + req := compute.DiskAddRequest{ + ComputeID: computeRec.ID, + DiskName: diskConv["disk_name"].(string), + Size: uint64(diskConv["size"].(int)), + SepID: uint64(diskConv["sep_id"].(int)), } - if diskConv["sep_id"].(int) != 0 { - urlValues.Add("sepId", strconv.Itoa(diskConv["sep_id"].(int))) + + if diskConv["disk_type"].(string) != "" { + req.DiskType = diskConv["disk_type"].(string) } if diskConv["pool"].(string) != "" { - urlValues.Add("pool", diskConv["pool"].(string)) + req.Pool = diskConv["pool"].(string) } if diskConv["desc"].(string) != "" { - urlValues.Add("desc", diskConv["desc"].(string)) + req.Description = diskConv["desc"].(string) } if diskConv["image_id"].(int) != 0 { - urlValues.Add("imageId", strconv.Itoa(diskConv["image_id"].(int))) + req.ImageID = uint64(diskConv["image_id"].(int)) } - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskAddAPI, urlValues) + _, err := c.CloudAPI().Compute().DiskAdd(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } @@ -746,10 +809,13 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf if diskConv["disk_name"].(string) == "bootdisk" { continue } - urlValues = &url.Values{} - urlValues.Add("diskId", strconv.Itoa(diskConv["disk_id"].(int))) - urlValues.Add("size", strconv.Itoa(diskConv["size"].(int))) - _, err := c.DecortAPICall(ctx, "POST", DisksResizeAPI, urlValues) + req := compute.DiskResizeRequest{ + ComputeID: computeRec.ID, + DiskID: uint64(diskConv["disk_id"].(int)), + Size: uint64(diskConv["size"].(int)), + } + + _, err := c.CloudAPI().Compute().DiskResize(ctx, req) if err != nil { return diag.FromErr(err) } @@ -758,14 +824,18 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf } if d.HasChange("started") { - params := &url.Values{} - params.Add("computeId", d.Id()) if d.Get("started").(bool) { - if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, params); err != nil { + req := compute.StartRequest{ + ComputeID: computeRec.ID, + } + if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil { return diag.FromErr(err) } } else { - if _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, params); err != nil { + req := compute.StopRequest{ + ComputeID: computeRec.ID, + } + if _, err := c.CloudAPI().Compute().Stop(ctx, req); err != nil { return diag.FromErr(err) } } @@ -773,19 +843,25 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf if d.HasChange("affinity_label") { affinityLabel := d.Get("affinity_label").(string) - urlValues.Add("computeId", d.Id()) if affinityLabel == "" { - _, err := c.DecortAPICall(ctx, "POST", ComputeAffinityLabelRemoveAPI, urlValues) + req := compute.AffinityLabelRemoveRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().AffinityLabelRemove(ctx, req) if err != nil { return diag.FromErr(err) } } - urlValues.Add("affinityLabel", affinityLabel) - _, err := c.DecortAPICall(ctx, "POST", ComputeAffinityLabelSetAPI, urlValues) + req := compute.AffinityLabelSetRequest{ + ComputeID: computeRec.ID, + AffinityLabel: affinityLabel, + } + + _, err := c.CloudAPI().Compute().AffinityLabelSet(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if d.HasChange("affinity_rules") { @@ -797,9 +873,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf newConv := newAR.([]interface{}) if len(newConv) == 0 { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", ComputeAffinityRulesClearAPI, urlValues) + req := compute.AffinityRulesClearRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().AffinityRulesClear(ctx, req) if err != nil { return diag.FromErr(err) } @@ -816,38 +894,39 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf } if len(deletedAR) > 0 { - urlValues := &url.Values{} for _, ar := range deletedAR { arConv := ar.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("topology", arConv["topology"].(string)) - urlValues.Add("policy", arConv["policy"].(string)) - urlValues.Add("mode", arConv["mode"].(string)) - urlValues.Add("key", arConv["key"].(string)) - urlValues.Add("value", arConv["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeAffinityRuleRemoveAPI, urlValues) + req := compute.AffinityRuleRemoveRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AffinityRuleRemove(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(addedAR) > 0 { for _, ar := range addedAR { arConv := ar.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("topology", arConv["topology"].(string)) - urlValues.Add("policy", arConv["policy"].(string)) - urlValues.Add("mode", arConv["mode"].(string)) - urlValues.Add("key", arConv["key"].(string)) - urlValues.Add("value", arConv["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeAffinityRuleAddAPI, urlValues) + req := compute.AffinityRuleAddRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AffinityRuleAdd(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } } @@ -863,9 +942,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf newConv := newAR.([]interface{}) if len(newConv) == 0 { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", ComputeAntiAffinityRulesClearAPI, urlValues) + req := compute.AntiAffinityRulesClearRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().AntiAffinityRulesClear(ctx, req) if err != nil { return diag.FromErr(err) } @@ -882,38 +963,39 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf } if len(deletedAR) > 0 { - urlValues := &url.Values{} for _, ar := range deletedAR { arConv := ar.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("topology", arConv["topology"].(string)) - urlValues.Add("policy", arConv["policy"].(string)) - urlValues.Add("mode", arConv["mode"].(string)) - urlValues.Add("key", arConv["key"].(string)) - urlValues.Add("value", arConv["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeAntiAffinityRuleRemoveAPI, urlValues) + req := compute.AntiAffinityRuleRemoveRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AntiAffinityRuleRemove(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(addedAR) > 0 { for _, ar := range addedAR { arConv := ar.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("topology", arConv["topology"].(string)) - urlValues.Add("policy", arConv["policy"].(string)) - urlValues.Add("mode", arConv["mode"].(string)) - urlValues.Add("key", arConv["key"].(string)) - urlValues.Add("value", arConv["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeAntiAffinityRuleAddAPI, urlValues) + req := compute.AntiAffinityRuleAddRequest{ + ComputeID: computeRec.ID, + Topology: arConv["topology"].(string), + Policy: arConv["policy"].(string), + Mode: arConv["mode"].(string), + Key: arConv["key"].(string), + Value: arConv["value"].(string), + } + + _, err := c.CloudAPI().Compute().AntiAffinityRuleAdd(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } } @@ -925,12 +1007,13 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf deletedTags := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() if len(deletedTags) > 0 { for _, tagInterface := range deletedTags { - urlValues := &url.Values{} tagItem := tagInterface.(map[string]interface{}) + req := compute.TagRemoveRequest{ + ComputeID: computeRec.ID, + Key: tagItem["key"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("key", tagItem["key"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeTagRemoveAPI, urlValues) + _, err := c.CloudAPI().Compute().TagRemove(ctx, req) if err != nil { return diag.FromErr(err) } @@ -940,13 +1023,14 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf addedTags := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() if len(addedTags) > 0 { for _, tagInterface := range addedTags { - urlValues := &url.Values{} tagItem := tagInterface.(map[string]interface{}) + req := compute.TagAddRequest{ + ComputeID: computeRec.ID, + Key: tagItem["key"].(string), + Value: tagItem["value"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("key", tagItem["key"].(string)) - urlValues.Add("value", tagItem["value"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeTagAddAPI, urlValues) + _, err := c.CloudAPI().Compute().TagAdd(ctx, req) if err != nil { return diag.FromErr(err) } @@ -959,19 +1043,21 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf deletedPfws := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() if len(deletedPfws) > 0 { for _, pfwInterface := range deletedPfws { - urlValues := &url.Values{} pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWDelRequest{ + ComputeID: computeRec.ID, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + LocalBasePort: uint64(pfwItem["local_port"].(int)), + Proto: pfwItem["proto"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("publicPortStart", strconv.Itoa(pfwItem["public_port_start"].(int))) if pfwItem["public_port_end"].(int) == -1 { - urlValues.Add("publicPortEnd", strconv.Itoa(pfwItem["public_port_start"].(int))) + req.PublicPortEnd = req.PublicPortStart } else { - urlValues.Add("publicPortEnd", strconv.Itoa(pfwItem["public_port_end"].(int))) + req.PublicPortEnd = uint64(pfwItem["public_port_end"].(int)) } - urlValues.Add("localBasePort", strconv.Itoa(pfwItem["local_port"].(int))) - urlValues.Add("proto", pfwItem["proto"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputePfwDelAPI, urlValues) + + _, err := c.CloudAPI().Compute().PFWDel(ctx, req) if err != nil { return diag.FromErr(err) } @@ -981,15 +1067,16 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf addedPfws := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() if len(addedPfws) > 0 { for _, pfwInterface := range addedPfws { - urlValues := &url.Values{} pfwItem := pfwInterface.(map[string]interface{}) + req := compute.PFWAddRequest{ + ComputeID: computeRec.ID, + PublicPortStart: uint64(pfwItem["public_port_start"].(int)), + PublicPortEnd: uint64(pfwItem["public_port_end"].(int)), + LocalBasePort: uint64(pfwItem["local_port"].(int)), + Proto: pfwItem["proto"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("publicPortStart", strconv.Itoa(pfwItem["public_port_start"].(int))) - urlValues.Add("publicPortEnd", strconv.Itoa(pfwItem["public_port_end"].(int))) - urlValues.Add("localBasePort", strconv.Itoa(pfwItem["local_port"].(int))) - urlValues.Add("proto", pfwItem["proto"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputePfwAddAPI, urlValues) + _, err := c.CloudAPI().Compute().PFWAdd(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1002,12 +1089,13 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf deletedUserAcess := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() if len(deletedUserAcess) > 0 { for _, userAcessInterface := range deletedUserAcess { - urlValues := &url.Values{} userAccessItem := userAcessInterface.(map[string]interface{}) + req := compute.UserRevokeRequest{ + ComputeID: computeRec.ID, + Username: userAccessItem["username"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("userName", userAccessItem["username"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeUserRevokeAPI, urlValues) + _, err := c.CloudAPI().Compute().UserRevoke(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1017,13 +1105,14 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf addedUserAccess := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() if len(addedUserAccess) > 0 { for _, userAccessInterface := range addedUserAccess { - urlValues := &url.Values{} userAccessItem := userAccessInterface.(map[string]interface{}) + req := compute.UserGrantRequest{ + ComputeID: computeRec.ID, + Username: userAccessItem["username"].(string), + AccessType: userAccessItem["access_type"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("userName", userAccessItem["username"].(string)) - urlValues.Add("accesstype", userAccessItem["access_type"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeUserGrantAPI, urlValues) + _, err := c.CloudAPI().Compute().UserGrant(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1036,12 +1125,13 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf deletedSnapshots := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() if len(deletedSnapshots) > 0 { for _, snapshotInterface := range deletedSnapshots { - urlValues := &url.Values{} snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotDeleteRequest{ + ComputeID: computeRec.ID, + Label: snapshotItem["label"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("label", snapshotItem["label"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeSnapshotDeleteAPI, urlValues) + _, err := c.CloudAPI().Compute().SnapshotDelete(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1051,12 +1141,13 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf addedSnapshots := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() if len(addedSnapshots) > 0 { for _, snapshotInterface := range addedSnapshots { - urlValues := &url.Values{} snapshotItem := snapshotInterface.(map[string]interface{}) + req := compute.SnapshotCreateRequest{ + ComputeID: computeRec.ID, + Label: snapshotItem["label"].(string), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("label", snapshotItem["label"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeSnapshotCreateAPI, urlValues) + _, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1066,23 +1157,25 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf if d.HasChange("rollback") { if rollback, ok := d.GetOk("rollback"); ok { - urlValues := &url.Values{} + req := compute.StopRequest{ + ComputeID: computeRec.ID, + Force: false, + } - //Compute must be stopped before rollback - urlValues.Add("computeId", d.Id()) - urlValues.Add("force", "false") - _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, urlValues) + _, err := c.CloudAPI().Compute().Stop(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} rollbackInterface := rollback.(*schema.Set).List()[0] rollbackItem := rollbackInterface.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("label", rollbackItem["label"].(string)) - _, err = c.DecortAPICall(ctx, "POST", ComputeSnapshotRollbackAPI, urlValues) + rollbackReq := compute.SnapshotRollbackRequest{ + ComputeID: computeRec.ID, + Label: rollbackItem["label"].(string), + } + + _, err = c.CloudAPI().Compute().SnapshotRollback(ctx, rollbackReq) if err != nil { return diag.FromErr(err) } @@ -1093,10 +1186,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf oldSet, newSet := d.GetChange("cd") deletedCd := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() if len(deletedCd) > 0 { - urlValues := &url.Values{} + req := compute.CDEjectRequest{ + ComputeID: computeRec.ID, + } - urlValues.Add("computeId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", ComputeCdEjectAPI, urlValues) + _, err := c.CloudAPI().Compute().CDEject(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1104,12 +1198,13 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf addedCd := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() if len(addedCd) > 0 { - urlValues := &url.Values{} cdItem := addedCd[0].(map[string]interface{}) + req := compute.CDInsertRequest{ + ComputeID: computeRec.ID, + CDROMID: uint64(cdItem["cdrom_id"].(int)), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("cdromId", strconv.Itoa(cdItem["cdrom_id"].(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeCdInsertAPI, urlValues) + _, err := c.CloudAPI().Compute().CDInsert(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1118,16 +1213,22 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf if d.HasChange("pin_to_stack") { oldPin, newPin := d.GetChange("pin_to_stack") - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) if oldPin.(bool) == true && newPin.(bool) == false { - _, err := c.DecortAPICall(ctx, "POST", ComputeUnpinFromStackAPI, urlValues) + req := compute.UnpinFromStackRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().UnpinFromStack(ctx, req) if err != nil { return diag.FromErr(err) } } if oldPin.(bool) == false && newPin.(bool) == true { - _, err := c.DecortAPICall(ctx, "POST", ComputePinToStackAPI, urlValues) + req := compute.PinToStackRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().PinToStack(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1136,16 +1237,21 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf if d.HasChange("pause") { oldPause, newPause := d.GetChange("pause") - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) if oldPause.(bool) == true && newPause.(bool) == false { - _, err := c.DecortAPICall(ctx, "POST", ComputeResumeAPI, urlValues) + req := compute.ResumeRequest{ + ComputeID: computeRec.ID, + } + _, err := c.CloudAPI().Compute().Resume(ctx, req) if err != nil { return diag.FromErr(err) } } if oldPause.(bool) == false && newPause.(bool) == true { - _, err := c.DecortAPICall(ctx, "POST", ComputePauseAPI, urlValues) + req := compute.PauseRequest{ + ComputeID: computeRec.ID, + } + + _, err := c.CloudAPI().Compute().Pause(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1154,45 +1260,49 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf if d.HasChange("reset") { oldReset, newReset := d.GetChange("reset") - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) if oldReset.(bool) == false && newReset.(bool) == true { - _, err := c.DecortAPICall(ctx, "POST", ComputeResetAPI, urlValues) + req := compute.ResetRequest{ + ComputeID: computeRec.ID, + } + _, err := c.CloudAPI().Compute().Reset(ctx, req) if err != nil { return diag.FromErr(err) } } } - //redeploy if d.HasChange("image_id") { oldImage, newImage := d.GetChange("image_id") - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("force", "false") - _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, urlValues) + stopReq := compute.StopRequest{ + ComputeID: computeRec.ID, + Force: false, + } + + _, err := c.CloudAPI().Compute().Stop(ctx, stopReq) if err != nil { return diag.FromErr(err) } if oldImage.(int) != newImage.(int) { - urlValues := &url.Values{} + req := compute.RedeployRequest{ + ComputeID: computeRec.ID, + ImageID: uint64(newImage.(int)), + } - urlValues.Add("computeId", d.Id()) - urlValues.Add("imageId", strconv.Itoa(newImage.(int))) if diskSize, ok := d.GetOk("boot_disk_size"); ok { - urlValues.Add("diskSize", strconv.Itoa(diskSize.(int))) + req.DiskSize = uint64(diskSize.(int)) } if dataDisks, ok := d.GetOk("data_disks"); ok { - urlValues.Add("dataDisks", dataDisks.(string)) + req.DataDisks = dataDisks.(string) } if autoStart, ok := d.GetOk("auto_start"); ok { - urlValues.Add("autoStart", strconv.FormatBool(autoStart.(bool))) + req.AutoStart = autoStart.(bool) } if forceStop, ok := d.GetOk("force_stop"); ok { - urlValues.Add("forceStop", strconv.FormatBool(forceStop.(bool))) + req.ForceStop = forceStop.(bool) } - _, err := c.DecortAPICall(ctx, "POST", ComputeRedeployAPI, urlValues) + + _, err := c.CloudAPI().Compute().Redeploy(ctx, req) if err != nil { return diag.FromErr(err) } @@ -1251,13 +1361,14 @@ func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interf d.Get("name").(string), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.DeleteRequest{ + ComputeID: computeId, + Permanently: d.Get("permanently").(bool), + DetachDisks: d.Get("detach_disks").(bool), + } - params := &url.Values{} - params.Add("computeId", d.Id()) - params.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) - params.Add("detachDisks", strconv.FormatBool(d.Get("detach_disks").(bool))) - - if _, err := c.DecortAPICall(ctx, "POST", ComputeDeleteAPI, params); err != nil { + if _, err := c.CloudAPI().Compute().Delete(ctx, req); err != nil { return diag.FromErr(err) } @@ -1276,6 +1387,12 @@ func disksSubresourceSchemaMake() map[string]*schema.Schema { Required: true, Description: "Disk size in GiB", }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: "Storage endpoint provider ID; by default the same with boot disk", + }, "disk_type": { Type: schema.TypeString, Computed: true, @@ -1283,12 +1400,6 @@ func disksSubresourceSchemaMake() map[string]*schema.Schema { ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false), Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'", }, - "sep_id": { - Type: schema.TypeInt, - Computed: true, - Optional: true, - Description: "Storage endpoint provider ID; by default the same with boot disk", - }, "pool": { Type: schema.TypeString, Computed: true, @@ -1551,7 +1662,13 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema { Schema: disksSubresourceSchemaMake(), }, }, - + "boot_disk": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: disksSubresourceSchemaMake(), + }, + }, "sep_id": { Type: schema.TypeInt, Optional: true, @@ -1559,7 +1676,6 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema { ForceNew: true, Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.", }, - "pool": { Type: schema.TypeString, Optional: true, diff --git a/internal/service/cloudapi/kvmvm/utility_compute.go b/internal/service/cloudapi/kvmvm/utility_compute.go index 3135dfb..9e12d49 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute.go +++ b/internal/service/cloudapi/kvmvm/utility_compute.go @@ -34,30 +34,20 @@ package kvmvm import ( "context" - "encoding/json" - "fmt" - "net/url" + "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error { - // d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key - // If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to - // update compute configuration accordingly - // Otherwise it will apply whatever is found in the new set of "extra_disks" right away. - // Primary use of do_delta=false is when calling this function from compute Create handler. - - // Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual - // disks via atomic API calls. However, it will not retry failed manipulation on the same disk. c := m.(*controller.ControllerCfg) log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta) - // NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt old_set, new_set := d.GetChange("extra_disks") apiErrCount := 0 @@ -69,12 +59,14 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa } for _, disk := range new_set.(*schema.Set).List() { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.DiskAttachRequest{ + ComputeID: computeId, + DiskID: uint64(disk.(int)), + } + + _, err := c.CloudAPI().Compute().DiskAttach(ctx, req) if err != nil { - // failed to attach extra disk - partial resource update apiErrCount++ lastSavedError = err } @@ -93,29 +85,34 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id()) if detach_set.Len() > 0 { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("force", "false") - _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, urlValues) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + stopReq := compute.StopRequest{ + ComputeID: computeId, + Force: false, + } + _, err := c.CloudAPI().Compute().Stop(ctx, stopReq) if err != nil { return err } + for _, diskId := range detach_set.List() { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskDetachAPI, urlValues) + req := compute.DiskDetachRequest{ + ComputeID: computeId, + DiskID: uint64(diskId.(int)), + } + _, err := c.CloudAPI().Compute().DiskDetach(ctx, req) if err != nil { - // failed to detach disk - there will be partial resource update log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err) apiErrCount++ lastSavedError = err } } - urlValues = &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("altBootId", "0") - _, err = c.DecortAPICall(ctx, "POST", ComputeStartAPI, urlValues) + + req := compute.StartRequest{ + ComputeID: computeId, + AltBootID: 0, + } + _, err = c.CloudAPI().Compute().Start(ctx, req) if err != nil { return err } @@ -124,12 +121,14 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id()) for _, diskId := range attach_set.List() { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.DiskAttachRequest{ + ComputeID: computeId, + DiskID: uint64(diskId.(int)), + } + + _, err := c.CloudAPI().Compute().DiskAttach(ctx, req) if err != nil { - // failed to attach disk - there will be partial resource update log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err) apiErrCount++ lastSavedError = err @@ -146,12 +145,6 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa } func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool, skip_zero bool) error { - // "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key - // If do_delta is true, this function will identify changes between new and existing specs for network and try to - // update compute configuration accordingly - // Otherwise it will apply whatever is found in the new set of "network" right away. - // Primary use of do_delta=false is when calling this function from compute Create handler. - c := m.(*controller.ControllerCfg) old_set, new_set := d.GetChange("network") @@ -168,18 +161,20 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData if i == 0 && skip_zero { continue } - urlValues := &url.Values{} net_data := runner.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("netType", net_data["net_type"].(string)) - urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int))) - ipaddr, ipSet := net_data["ip_address"] // "ip_address" key is optional + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.NetAttachRequest{ + ComputeID: computeId, + NetType: net_data["net_type"].(string), + NetID: uint64(net_data["net_id"].(int)), + } + + ipaddr, ipSet := net_data["ip_address"] if ipSet { - urlValues.Add("ipAddr", ipaddr.(string)) + req.IPAddr = ipaddr.(string) } - _, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues) + _, err := c.CloudAPI().Compute().NetAttach(ctx, req) if err != nil { - // failed to attach network - partial resource update apiErrCount++ lastSavedError = err } @@ -196,14 +191,16 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id()) for _, runner := range detach_set.List() { - urlValues := &url.Values{} net_data := runner.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("ipAddr", net_data["ip_address"].(string)) - urlValues.Add("mac", net_data["mac"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeNetDetachAPI, urlValues) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.NetDetachRequest{ + ComputeID: computeId, + IPAddr: net_data["ip_address"].(string), + MAC: net_data["mac"].(string), + } + + _, err := c.CloudAPI().Compute().NetDetach(ctx, req) if err != nil { - // failed to detach this network - there will be partial resource update log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s", net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err) apiErrCount++ @@ -214,17 +211,20 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id()) for _, runner := range attach_set.List() { - urlValues := &url.Values{} net_data := runner.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int))) - urlValues.Add("netType", net_data["net_type"].(string)) + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.NetAttachRequest{ + ComputeID: computeId, + NetType: net_data["net_type"].(string), + NetID: uint64(net_data["net_id"].(int)), + } + if net_data["ip_address"].(string) != "" { - urlValues.Add("ipAddr", net_data["ip_address"].(string)) + req.IPAddr = net_data["ip_address"].(string) } - _, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues) + + _, err := c.CloudAPI().Compute().NetAttach(ctx, req) if err != nil { - // failed to attach this network - there will be partial resource update log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s", net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err) apiErrCount++ @@ -241,20 +241,17 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData return nil } -func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (RecordCompute, error) { +func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.RecordCompute, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - compute := &RecordCompute{} - - urlValues.Add("computeId", d.Id()) - computeRaw, err := c.DecortAPICall(ctx, "POST", ComputeGetAPI, urlValues) - if err != nil { - return *compute, err + computeId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := compute.GetRequest{ + ComputeID: computeId, } - err = json.Unmarshal([]byte(computeRaw), &compute) + computeRecord, err := c.CloudAPI().Compute().Get(ctx, req) if err != nil { - return *compute, err + return *computeRecord, err } - return *compute, nil + + return *computeRecord, nil } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_audits.go b/internal/service/cloudapi/kvmvm/utility_compute_audits.go index a80950c..c1524f4 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_audits.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_audits.go @@ -34,28 +34,21 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityComputeAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListAudits, error) { +func utilityComputeAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListAudits, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - computeAudits := &ListAudits{} - - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - computeAuditsRaw, err := c.DecortAPICall(ctx, "POST", ComputeAuditsAPI, urlValues) - if err != nil { - return nil, err + req := compute.AuditsRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), } - err = json.Unmarshal([]byte(computeAuditsRaw), &computeAudits) + computeAudits, err := c.CloudAPI().Compute().Audits(ctx, req) if err != nil { return nil, err } - return *computeAudits, nil + return computeAudits, nil } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_boot_disk.go b/internal/service/cloudapi/kvmvm/utility_compute_boot_disk.go index 850626a..ed9a9a0 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_boot_disk.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_boot_disk.go @@ -36,16 +36,17 @@ import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" ) -func utilityComputeBootDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*ItemComputeDisk, error) { - compute, err := utilityComputeCheckPresence(ctx, d, m) +func utilityComputeBootDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemComputeDisk, error) { + computeRecord, err := utilityComputeCheckPresence(ctx, d, m) if err != nil { return nil, err } - bootDisk := &ItemComputeDisk{} - for _, disk := range compute.Disks { + bootDisk := &compute.ItemComputeDisk{} + for _, disk := range computeRecord.Disks { if disk.Name == "bootdisk" { *bootDisk = disk break diff --git a/internal/service/cloudapi/kvmvm/utility_compute_get_audits.go b/internal/service/cloudapi/kvmvm/utility_compute_get_audits.go index ec0fe1f..92a9fdb 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_get_audits.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_get_audits.go @@ -34,28 +34,22 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityComputeGetAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListShortAudits, error) { +func utilityComputeGetAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListShortAudits, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - computeAudits := &ListShortAudits{} - - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - computeAuditsRaw, err := c.DecortAPICall(ctx, "POST", ComputeGetAuditsAPI, urlValues) - if err != nil { - return nil, err + req := compute.GetAuditsRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), } - err = json.Unmarshal([]byte(computeAuditsRaw), &computeAudits) + computeAudits, err := c.CloudAPI().Compute().GetAudits(ctx, req) if err != nil { return nil, err } - return *computeAudits, nil + + return computeAudits, nil } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_get_console_url.go b/internal/service/cloudapi/kvmvm/utility_compute_get_console_url.go index cba140b..856ef6e 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_get_console_url.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_get_console_url.go @@ -34,22 +34,22 @@ package kvmvm import ( "context" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func utilityComputeGetConsoleUrlCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - computeConsoleUrlRaw, err := c.DecortAPICall(ctx, "POST", ComputeGetConsoleUrlAPI, urlValues) + req := compute.GetConsoleURLRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } + computeConsoleUrl, err := c.CloudAPI().Compute().GetConsoleURL(ctx, req) if err != nil { return "", err } - return string(computeConsoleUrlRaw), nil + return computeConsoleUrl, nil } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_get_log.go b/internal/service/cloudapi/kvmvm/utility_compute_get_log.go index a2eb226..d80ae41 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_get_log.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_get_log.go @@ -34,23 +34,23 @@ package kvmvm import ( "context" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func utilityComputeGetLogCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := compute.GetLogRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Path: d.Get("path").(string), + } - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("path", d.Get("path").(string)) - computeGetLogRaw, err := c.DecortAPICall(ctx, "POST", ComputeGetLogAPI, urlValues) + computeGetLog, err := c.CloudAPI().Compute().GetLog(ctx, req) if err != nil { return "", err } - return string(computeGetLogRaw), nil + return computeGetLog, nil } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_list.go b/internal/service/cloudapi/kvmvm/utility_compute_list.go index 8b9cff2..b5e3f1b 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_list.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_list.go @@ -34,38 +34,30 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityDataComputeListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListComputes, error) { +func utilityDataComputeListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListComputes, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - listComputes := &ListComputes{} + req := compute.ListRequest{} if includeDeleted, ok := d.GetOk("includedeleted"); ok { - urlValues.Add("includeDeleted", strconv.FormatBool(includeDeleted.(bool))) + req.IncludeDeleted = includeDeleted.(bool) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } - listComputesRaw, err := c.DecortAPICall(ctx, "POST", ComputeListAPI, urlValues) + listComputes, err := c.CloudAPI().Compute().List(ctx, req) if err != nil { return nil, err } - err = json.Unmarshal([]byte(listComputesRaw), &listComputes) - if err != nil { - return nil, err - } - return *listComputes, nil - + return listComputes, nil } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_pfw_list.go b/internal/service/cloudapi/kvmvm/utility_compute_pfw_list.go index 4002758..308a862 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_pfw_list.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_pfw_list.go @@ -34,29 +34,23 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityComputePfwListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListPFWs, error) { +func utilityComputePfwListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListPFWs, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - listPFWs := &ListPFWs{} - - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - computePfwListRaw, err := c.DecortAPICall(ctx, "POST", ComputePfwListAPI, urlValues) - if err != nil { - return nil, err + req := compute.PFWListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), } - err = json.Unmarshal([]byte(computePfwListRaw), &listPFWs) + listPFWs, err := c.CloudAPI().Compute().PFWList(ctx, req) if err != nil { return nil, err } - return *listPFWs, err + + return listPFWs, err } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_snapshot_usage.go b/internal/service/cloudapi/kvmvm/utility_compute_snapshot_usage.go index 9e9dcdd..f2458a1 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_snapshot_usage.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_snapshot_usage.go @@ -2,32 +2,27 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityComputeSnapshotUasgeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListUsageSnapshots, error) { +func utilityComputeSnapshotUsageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListUsageSnapshots, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - UsageSnapshotList := &ListUsageSnapshots{} + req := compute.SnapshotUsageRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) if label, ok := d.GetOk("label"); ok { - urlValues.Add("label", label.(string)) - } - computeSnapshotUsage, err := c.DecortAPICall(ctx, "POST", ComputeSnapshotUsageAPI, urlValues) - if err != nil { - return nil, err + req.Label = label.(string) } - err = json.Unmarshal([]byte(computeSnapshotUsage), &UsageSnapshotList) + computeSnapshotUsage, err := c.CloudAPI().Compute().SnapshotUsage(ctx, req) if err != nil { return nil, err } - return *UsageSnapshotList, err + + return computeSnapshotUsage, err } diff --git a/internal/service/cloudapi/kvmvm/utility_compute_user_list.go b/internal/service/cloudapi/kvmvm/utility_compute_user_list.go index cc3a1e2..684471f 100644 --- a/internal/service/cloudapi/kvmvm/utility_compute_user_list.go +++ b/internal/service/cloudapi/kvmvm/utility_compute_user_list.go @@ -34,27 +34,22 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityComputeUserListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (RecordACL, error) { +func utilityComputeUserListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.RecordACL, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - userList := &RecordACL{} - - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - computeUserListRaw, err := c.DecortAPICall(ctx, "POST", ComputeUserListAPI, urlValues) - if err != nil { - return *userList, err + req := compute.UserListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), } - err = json.Unmarshal([]byte(computeUserListRaw), &userList) + + computeUserList, err := c.CloudAPI().Compute().UserList(ctx, req) if err != nil { - return *userList, err + return *computeUserList, err } - return *userList, err + + return *computeUserList, err } diff --git a/internal/service/cloudapi/kvmvm/utility_data_source_compute.go b/internal/service/cloudapi/kvmvm/utility_data_source_compute.go index e99b6c9..86407bf 100644 --- a/internal/service/cloudapi/kvmvm/utility_data_source_compute.go +++ b/internal/service/cloudapi/kvmvm/utility_data_source_compute.go @@ -34,28 +34,22 @@ package kvmvm import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityDataComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (RecordCompute, error) { +func utilityDataComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.RecordCompute, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - compute := &RecordCompute{} - - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - computeRaw, err := c.DecortAPICall(ctx, "POST", ComputeGetAPI, urlValues) - if err != nil { - return *compute, err + req := compute.GetRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), } - err = json.Unmarshal([]byte(computeRaw), &compute) + computeRecord, err := c.CloudAPI().Compute().Get(ctx, req) if err != nil { - return *compute, err + return *computeRecord, err } - return *compute, nil + + return *computeRecord, nil } diff --git a/internal/service/cloudapi/lb/api.go b/internal/service/cloudapi/lb/api.go deleted file mode 100644 index 5adc68d..0000000 --- a/internal/service/cloudapi/lb/api.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package lb - -const lbListAPI = "/restmachine/cloudapi/lb/list" -const lbListDeletedAPI = "/restmachine/cloudapi/lb/listDeleted" -const lbGetAPI = "/restmachine/cloudapi/lb/get" -const lbCreateAPI = "/restmachine/cloudapi/lb/create" -const lbDeleteAPI = "/restmachine/cloudapi/lb/delete" -const lbDisableAPI = "/restmachine/cloudapi/lb/disable" -const lbEnableAPI = "/restmachine/cloudapi/lb/enable" -const lbUpdateAPI = "/restmachine/cloudapi/lb/update" -const lbStartAPI = "/restmachine/cloudapi/lb/start" -const lbStopAPI = "/restmachine/cloudapi/lb/stop" -const lbRestartAPI = "/restmachine/cloudapi/lb/restart" -const lbRestoreAPI = "/restmachine/cloudapi/lb/restore" -const lbConfigResetAPI = "/restmachine/cloudapi/lb/configReset" -const lbBackendCreateAPI = "/restmachine/cloudapi/lb/backendCreate" -const lbBackendDeleteAPI = "/restmachine/cloudapi/lb/backendDelete" -const lbBackendUpdateAPI = "/restmachine/cloudapi/lb/backendUpdate" -const lbBackendServerAddAPI = "/restmachine/cloudapi/lb/backendServerAdd" -const lbBackendServerDeleteAPI = "/restmachine/cloudapi/lb/backendServerDelete" -const lbBackendServerUpdateAPI = "/restmachine/cloudapi/lb/backendServerUpdate" -const lbFrontendCreateAPI = "/restmachine/cloudapi/lb/frontendCreate" -const lbFrontendDeleteAPI = "/restmachine/cloudapi/lb/frontendDelete" -const lbFrontendBindAPI = "/restmachine/cloudapi/lb/frontendBind" -const lbFrontendBindDeleteAPI = "/restmachine/cloudapi/lb/frontendBindDelete" -const lbFrontendBindUpdateAPI = "/restmachine/cloudapi/lb/frontendBindingUpdate" diff --git a/internal/service/cloudapi/lb/data_source_lb.go b/internal/service/cloudapi/lb/data_source_lb.go index 1e29660..acbe98e 100644 --- a/internal/service/cloudapi/lb/data_source_lb.go +++ b/internal/service/cloudapi/lb/data_source_lb.go @@ -41,33 +41,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenLB(d *schema.ResourceData, lb *LoadBalancer) { - d.Set("ha_mode", lb.HAMode) - d.Set("backends", flattenLBBackends(lb.Backends)) - d.Set("created_by", lb.CreatedBy) - d.Set("created_time", lb.CreatedTime) - d.Set("deleted_by", lb.DeletedBy) - d.Set("deleted_time", lb.DeletedTime) - d.Set("desc", lb.Description) - d.Set("dp_api_user", lb.DPAPIUser) - d.Set("extnet_id", lb.ExtnetId) - d.Set("frontends", flattenFrontends(lb.Frontends)) - d.Set("gid", lb.GID) - d.Set("guid", lb.GUID) - d.Set("image_id", lb.ImageId) - d.Set("milestones", lb.Milestones) - d.Set("name", lb.Name) - d.Set("primary_node", flattenNode(lb.PrimaryNode)) - d.Set("rg_id", lb.RGID) - d.Set("rg_name", lb.RGName) - d.Set("secondary_node", flattenNode(lb.SecondaryNode)) - d.Set("status", lb.Status) - d.Set("tech_status", lb.TechStatus) - d.Set("updated_by", lb.UpdatedBy) - d.Set("updated_time", lb.UpdatedTime) - d.Set("vins_id", lb.VinsId) -} - func dataSourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { lb, err := utilityLBCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudapi/lb/data_source_lb_list.go b/internal/service/cloudapi/lb/data_source_lb_list.go index 59cec33..f4efdce 100644 --- a/internal/service/cloudapi/lb/data_source_lb_list.go +++ b/internal/service/cloudapi/lb/data_source_lb_list.go @@ -41,41 +41,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenLBList(lbl LBList) []map[string]interface{} { - res := make([]map[string]interface{}, 0, len(lbl)) - for _, lb := range lbl { - temp := map[string]interface{}{ - "ha_mode": lb.HAMode, - "backends": flattenLBBackends(lb.Backends), - "created_by": lb.CreatedBy, - "created_time": lb.CreatedTime, - "deleted_by": lb.DeletedBy, - "deleted_time": lb.DeletedTime, - "desc": lb.Description, - "dp_api_user": lb.DPAPIUser, - "dp_api_password": lb.DPAPIPassword, - "extnet_id": lb.ExtnetId, - "frontends": flattenFrontends(lb.Frontends), - "gid": lb.GID, - "guid": lb.GUID, - "image_id": lb.ImageId, - "milestones": lb.Milestones, - "name": lb.Name, - "primary_node": flattenNode(lb.PrimaryNode), - "rg_id": lb.RGID, - "rg_name": lb.RGName, - "secondary_node": flattenNode(lb.SecondaryNode), - "status": lb.Status, - "tech_status": lb.TechStatus, - "updated_by": lb.UpdatedBy, - "updated_time": lb.UpdatedTime, - "vins_id": lb.VinsId, - } - res = append(res, temp) - } - return res -} - func dataSourceLBListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { lbList, err := utilityLBListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudapi/lb/flattens.go b/internal/service/cloudapi/lb/flattens.go index d9c6b9f..96bba63 100644 --- a/internal/service/cloudapi/lb/flattens.go +++ b/internal/service/cloudapi/lb/flattens.go @@ -32,15 +32,128 @@ Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/w package lb -func flattenNode(node Node) []map[string]interface{} { +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" +) + +func flattenLBFrontendBind(d *schema.ResourceData, b *lb.ItemBinding, lbId int64, frontendName string) { + d.Set("lb_id", lbId) + d.Set("frontend_name", frontendName) + d.Set("name", b.Name) + d.Set("address", b.Address) + d.Set("guid", b.GUID) + d.Set("port", b.Port) +} + +func flattenLBFrontend(d *schema.ResourceData, f *lb.ItemFrontend, lbId int64) { + d.Set("lb_id", lbId) + d.Set("backend_name", f.Backend) + d.Set("name", f.Name) + d.Set("guid", f.GUID) + d.Set("bindings", flattendBindings(f.Bindings)) +} + +func flattenResourceLBBackendServer(d *schema.ResourceData, s *lb.ItemServer, lbId int64, backendName string) { + d.Set("lb_id", lbId) + d.Set("backend_name", backendName) + d.Set("name", s.Name) + d.Set("port", s.Port) + d.Set("address", s.Address) + d.Set("check", s.Check) + d.Set("guid", s.GUID) + d.Set("downinter", s.ServerSettings.DownInter) + d.Set("fall", s.ServerSettings.Fall) + d.Set("inter", s.ServerSettings.Inter) + d.Set("maxconn", s.ServerSettings.MaxConn) + d.Set("maxqueue", s.ServerSettings.MaxQueue) + d.Set("rise", s.ServerSettings.Rise) + d.Set("slowstart", s.ServerSettings.SlowStart) + d.Set("weight", s.ServerSettings.Weight) + +} + +func flattenResourceLBBackend(d *schema.ResourceData, b *lb.ItemBackend, lbId int64) { + d.Set("lb_id", lbId) + d.Set("name", b.Name) + d.Set("algorithm", b.Algorithm) + d.Set("guid", b.GUID) + d.Set("downinter", b.ServerDefaultSettings.DownInter) + d.Set("fall", b.ServerDefaultSettings.Fall) + d.Set("inter", b.ServerDefaultSettings.Inter) + d.Set("maxconn", b.ServerDefaultSettings.MaxConn) + d.Set("maxqueue", b.ServerDefaultSettings.MaxQueue) + d.Set("rise", b.ServerDefaultSettings.Rise) + d.Set("slowstart", b.ServerDefaultSettings.SlowStart) + d.Set("weight", b.ServerDefaultSettings.Weight) + d.Set("servers", flattenServers(b.Servers)) +} + +func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) { + d.Set("ha_mode", lb.HAMode) + d.Set("backends", flattenLBBackends(lb.Backends)) + d.Set("created_by", lb.CreatedBy) + d.Set("created_time", lb.CreatedTime) + d.Set("deleted_by", lb.DeletedBy) + d.Set("deleted_time", lb.DeletedTime) + d.Set("desc", lb.Description) + d.Set("dp_api_user", lb.DPAPIUser) + d.Set("extnet_id", lb.ExtNetID) + d.Set("frontends", flattenFrontends(lb.Frontends)) + d.Set("gid", lb.GID) + d.Set("guid", lb.GUID) + d.Set("lb_id", lb.ID) + d.Set("image_id", lb.ImageID) + d.Set("milestones", lb.Milestones) + d.Set("name", lb.Name) + d.Set("primary_node", flattenNode(lb.PrimaryNode)) + d.Set("rg_id", lb.RGID) + d.Set("rg_name", lb.RGName) + d.Set("secondary_node", flattenNode(lb.SecondaryNode)) + d.Set("status", lb.Status) + d.Set("tech_status", lb.TechStatus) + d.Set("updated_by", lb.UpdatedBy) + d.Set("updated_time", lb.UpdatedTime) + d.Set("vins_id", lb.VINSID) + +} + +func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) { + d.Set("ha_mode", lb.HAMode) + d.Set("backends", flattenLBBackends(lb.Backends)) + d.Set("created_by", lb.CreatedBy) + d.Set("created_time", lb.CreatedTime) + d.Set("deleted_by", lb.DeletedBy) + d.Set("deleted_time", lb.DeletedTime) + d.Set("desc", lb.Description) + d.Set("dp_api_user", lb.DPAPIUser) + d.Set("extnet_id", lb.ExtNetID) + d.Set("frontends", flattenFrontends(lb.Frontends)) + d.Set("gid", lb.GID) + d.Set("guid", lb.GUID) + d.Set("image_id", lb.ImageID) + d.Set("milestones", lb.Milestones) + d.Set("name", lb.Name) + d.Set("primary_node", flattenNode(lb.PrimaryNode)) + d.Set("rg_id", lb.RGID) + d.Set("rg_name", lb.RGName) + d.Set("secondary_node", flattenNode(lb.SecondaryNode)) + d.Set("status", lb.Status) + d.Set("tech_status", lb.TechStatus) + d.Set("updated_by", lb.UpdatedBy) + d.Set("updated_time", lb.UpdatedTime) + d.Set("vins_id", lb.VINSID) +} + +func flattenNode(node lb.RecordNode) []map[string]interface{} { temp := make([]map[string]interface{}, 0) n := map[string]interface{}{ - "backend_ip": node.BackendIp, - "compute_id": node.ComputeId, - "frontend_ip": node.FrontendIp, + "backend_ip": node.BackendIP, + "compute_id": node.ComputeID, + "frontend_ip": node.FrontendIP, "guid": node.GUID, - "mgmt_ip": node.MGMTIp, - "network_id": node.NetworkId, + "mgmt_ip": node.MGMTIP, + "network_id": node.NetworkID, } temp = append(temp, n) @@ -48,7 +161,7 @@ func flattenNode(node Node) []map[string]interface{} { return temp } -func flattendBindings(bs []Binding) []map[string]interface{} { +func flattendBindings(bs []lb.ItemBinding) []map[string]interface{} { temp := make([]map[string]interface{}, 0, len(bs)) for _, b := range bs { t := map[string]interface{}{ @@ -62,7 +175,7 @@ func flattendBindings(bs []Binding) []map[string]interface{} { return temp } -func flattenFrontends(fs []Frontend) []map[string]interface{} { +func flattenFrontends(fs []lb.ItemFrontend) []map[string]interface{} { temp := make([]map[string]interface{}, 0, len(fs)) for _, f := range fs { t := map[string]interface{}{ @@ -77,7 +190,7 @@ func flattenFrontends(fs []Frontend) []map[string]interface{} { return temp } -func flattenServers(servers []Server) []map[string]interface{} { +func flattenServers(servers []lb.ItemServer) []map[string]interface{} { temp := make([]map[string]interface{}, 0, len(servers)) for _, server := range servers { t := map[string]interface{}{ @@ -94,7 +207,7 @@ func flattenServers(servers []Server) []map[string]interface{} { return temp } -func flattenServerSettings(defSet ServerSettings) []map[string]interface{} { +func flattenServerSettings(defSet lb.RecordServerSettings) []map[string]interface{} { temp := map[string]interface{}{ "downinter": defSet.DownInter, "fall": defSet.Fall, @@ -112,7 +225,7 @@ func flattenServerSettings(defSet ServerSettings) []map[string]interface{} { return res } -func flattenLBBackends(backends []Backend) []map[string]interface{} { +func flattenLBBackends(backends []lb.ItemBackend) []map[string]interface{} { temp := make([]map[string]interface{}, 0, len(backends)) for _, item := range backends { t := map[string]interface{}{ @@ -127,3 +240,39 @@ func flattenLBBackends(backends []Backend) []map[string]interface{} { } return temp } + +func flattenLBList(lbl lb.ListLB) []map[string]interface{} { + res := make([]map[string]interface{}, 0, len(lbl)) + for _, lb := range lbl { + temp := map[string]interface{}{ + "ha_mode": lb.HAMode, + "backends": flattenLBBackends(lb.Backends), + "created_by": lb.CreatedBy, + "created_time": lb.CreatedTime, + "deleted_by": lb.DeletedBy, + "deleted_time": lb.DeletedTime, + "desc": lb.Description, + "dp_api_user": lb.DPAPIUser, + "dp_api_password": lb.DPAPIPassword, + "extnet_id": lb.ExtNetID, + "frontends": flattenFrontends(lb.Frontends), + "gid": lb.GID, + "guid": lb.GUID, + "image_id": lb.ImageID, + "milestones": lb.Milestones, + "name": lb.Name, + "primary_node": flattenNode(lb.PrimaryNode), + "rg_id": lb.RGID, + "rg_name": lb.RGName, + "secondary_node": flattenNode(lb.SecondaryNode), + "status": lb.Status, + "tech_status": lb.TechStatus, + "updated_by": lb.UpdatedBy, + "updated_time": lb.UpdatedTime, + "vins_id": lb.VINSID, + "lb_id": lb.ID, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudapi/lb/resource_check_input_values.go b/internal/service/cloudapi/lb/resource_check_input_values.go index 0188f32..3318685 100644 --- a/internal/service/cloudapi/lb/resource_check_input_values.go +++ b/internal/service/cloudapi/lb/resource_check_input_values.go @@ -2,138 +2,67 @@ package lb import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func existLBID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + lbId := uint64(d.Get("lb_id").(int)) - lbList := []struct { - ID int `json:"id"` - }{} + req := lb.ListRequest{} - lbListAPI := "/restmachine/cloudapi/lb/list" - - lbListRaw, err := c.DecortAPICall(ctx, "POST", lbListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(lbListRaw), &lbList) + lbList, err := c.CloudAPI().LB().List(ctx, req) if err != nil { return false, err } - haveLB := false - lbId := d.Get("lb_id").(int) - - for _, lb := range lbList { - if lb.ID == lbId { - haveLB = true - break - } - } - - return haveLB, nil + return len(lbList.FilterByID(lbId)) != 0, nil } func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + rgId := uint64(d.Get("rg_id").(int)) - rgList := []struct { - ID int `json:"id"` - }{} + req := rg.ListRequest{} - rgListAPI := "/restmachine/cloudapi/rg/list" - - rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues) + rgList, err := c.CloudAPI().RG().List(ctx, req) if err != nil { return false, err } - err = json.Unmarshal([]byte(rgListRaw), &rgList) - if err != nil { - return false, err - } - - haveRG := false - rgId := d.Get("rg_id").(int) - for _, rg := range rgList { - if rg.ID == rgId { - haveRG = true - break - } - } - - return haveRG, nil + return len(rgList.FilterByID(rgId)) != 0, nil } func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + extNetID := uint64(d.Get("extnet_id").(int)) - extNetList := []struct { - ID int `json:"id"` - }{} + req := extnet.ListRequest{} - extNetListAPI := "/restmachine/cloudapi/extnet/list" - - extNetListRaw, err := c.DecortAPICall(ctx, "POST", extNetListAPI, urlValues) + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) if err != nil { return false, err } - err = json.Unmarshal([]byte(extNetListRaw), &extNetList) - if err != nil { - return false, err - } - - haveExtNet := false - extNetID := d.Get("extnet_id").(int) - for _, extNet := range extNetList { - if extNet.ID == extNetID { - haveExtNet = true - break - } - } - - return haveExtNet, nil + return len(extNetList.FilterByID(extNetID)) != 0, nil } func existViNSID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + vinsID := uint64(d.Get("vins_id").(int)) - vinsList := []struct { - ID int `json:"id"` - }{} + req := vins.ListRequest{} - vinsListAPI := "/restmachine/cloudapi/vins/list" - - vinsListRaw, err := c.DecortAPICall(ctx, "POST", vinsListAPI, urlValues) + vinsList, err := c.CloudAPI().VINS().List(ctx, req) if err != nil { return false, err } - err = json.Unmarshal([]byte(vinsListRaw), &vinsList) - if err != nil { - return false, err - } - - haveVins := false - vinsID := d.Get("vins_id").(int) - for _, vins := range vinsList { - if vins.ID == vinsID { - haveVins = true - break - } - } - - return haveVins, nil + return len(vinsList.FilterByID(vinsID)) != 0, nil } diff --git a/internal/service/cloudapi/lb/resource_lb.go b/internal/service/cloudapi/lb/resource_lb.go index 15431ac..af54ff4 100644 --- a/internal/service/cloudapi/lb/resource_lb.go +++ b/internal/service/cloudapi/lb/resource_lb.go @@ -34,12 +34,12 @@ package lb import ( "context" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/status" @@ -76,53 +76,53 @@ func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{} } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - urlValues.Add("extnetId", strconv.Itoa(d.Get("extnet_id").(int))) - urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int))) - urlValues.Add("start", strconv.FormatBool((d.Get("start").(bool)))) + req := lb.CreateRequest{ + Name: d.Get("name").(string), + RGID: uint64(d.Get("rg_id").(int)), + ExtNetID: uint64(d.Get("extnet_id").(int)), + VINSID: uint64(d.Get("vins_id").(int)), + Start: d.Get("start").(bool), + } if desc, ok := d.GetOk("desc"); ok { - urlValues.Add("desc", desc.(string)) + req.Description = desc.(string) } - lbId, err := c.DecortAPICall(ctx, "POST", lbCreateAPI, urlValues) + lbId, err := c.CloudAPI().LB().Create(ctx, req) if err != nil { return diag.FromErr(err) } + lbIdParsed, _ := strconv.ParseInt(lbId, 10, 64) + d.SetId(lbId) - d.Set("lb_id", lbId) + d.Set("lb_id", lbIdParsed) _, err = utilityLBCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - diagnostics := resourceLBRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - urlValues = &url.Values{} - if enable, ok := d.GetOk("enable"); ok { - api := lbDisableAPI - if enable.(bool) { - api = lbEnableAPI + lbId := uint64(d.Get("lb_id").(int)) + req := lb.DisableEnableRequest{ + LBID: lbId, } - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) + if enable.(bool) { + _, err := c.CloudAPI().LB().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + _, err := c.CloudAPI().LB().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } } - - urlValues = &url.Values{} } - return nil + return resourceLBRead(ctx, d, m) } func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -130,36 +130,37 @@ func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) c := m.(*controller.ControllerCfg) - lb, err := utilityLBCheckPresence(ctx, d, m) - if lb == nil { + lbRec, err := utilityLBCheckPresence(ctx, d, m) + if lbRec == nil { d.SetId("") return diag.FromErr(err) } hasChanged := false - switch lb.Status { + switch lbRec.Status { case status.Modeled: - return diag.Errorf("The LB is in status: %s, please, contact support for more information", lb.Status) + return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) case status.Creating: case status.Created: case status.Deleting: case status.Deleted: - urlValues := &url.Values{} - urlValues.Add("lbId", d.Id()) + lbId, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := lb.RestoreRequest{LBID: lbId} + enableReq := lb.DisableEnableRequest{LBID: lbId} - _, err := c.DecortAPICall(ctx, "POST", lbRestoreAPI, urlValues) + _, err := c.CloudAPI().LB().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", lbEnableAPI, urlValues) + _, err = c.CloudAPI().LB().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } hasChanged = true case status.Destroying: - return diag.Errorf("The LB is in progress with status: %s", lb.Status) + return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) case status.Destroyed: d.SetId("") return resourceLBCreate(ctx, d, m) @@ -167,43 +168,19 @@ func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) case status.Enabling: case status.Disabling: case status.Disabled: - log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lb.Status) + log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) case status.Restoring: } if hasChanged { - lb, err = utilityLBCheckPresence(ctx, d, m) + lbRec, err = utilityLBCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } } - d.Set("ha_mode", lb.HAMode) - d.Set("backends", flattenLBBackends(lb.Backends)) - d.Set("created_by", lb.CreatedBy) - d.Set("created_time", lb.CreatedTime) - d.Set("deleted_by", lb.DeletedBy) - d.Set("deleted_time", lb.DeletedTime) - d.Set("desc", lb.Description) - d.Set("dp_api_user", lb.DPAPIUser) - d.Set("extnet_id", lb.ExtnetId) - d.Set("frontends", flattenFrontends(lb.Frontends)) - d.Set("gid", lb.GID) - d.Set("guid", lb.GUID) - d.Set("lb_id", lb.ID) - d.Set("image_id", lb.ImageId) - d.Set("milestones", lb.Milestones) - d.Set("name", lb.Name) - d.Set("primary_node", flattenNode(lb.PrimaryNode)) - d.Set("rg_id", lb.RGID) - d.Set("rg_name", lb.RGName) - d.Set("secondary_node", flattenNode(lb.SecondaryNode)) - d.Set("status", lb.Status) - d.Set("tech_status", lb.TechStatus) - d.Set("updated_by", lb.UpdatedBy) - d.Set("updated_time", lb.UpdatedTime) - d.Set("vins_id", lb.VinsId) + flattenResourceLB(d, lbRec) return nil } @@ -211,35 +188,33 @@ func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) func resourceLBDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBDelete") - lb, err := utilityLBCheckPresence(ctx, d, m) - if lb == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityLBCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req := lb.DeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } if permanently, ok := d.GetOk("permanently"); ok { - urlValues.Add("permanently", strconv.FormatBool(permanently.(bool))) + req.Permanently = permanently.(bool) } - _, err = c.DecortAPICall(ctx, "POST", lbDeleteAPI, urlValues) + _, err = c.CloudAPI().LB().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceLBEdit") + log.Debugf("resourceLBUpdate") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} haveRGID, err := existRGID(ctx, d, m) if err != nil { @@ -268,36 +243,37 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{} return diag.Errorf("resourceLBUpdate: can't update LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int)) } - lb, err := utilityLBCheckPresence(ctx, d, m) - if lb == nil { + lbRec, err := utilityLBCheckPresence(ctx, d, m) + if lbRec == nil { d.SetId("") return diag.FromErr(err) } hasChanged := false - switch lb.Status { + switch lbRec.Status { case status.Modeled: - return diag.Errorf("The LB is in status: %s, please, contact support for more information", lb.Status) + return diag.Errorf("The LB is in status: %s, please, contact support for more information", lbRec.Status) case status.Creating: case status.Created: case status.Deleting: case status.Deleted: - urlValues := &url.Values{} - urlValues.Add("lbId", d.Id()) + lbId, _ := strconv.ParseUint(d.Id(), 10, 64) + restoreReq := lb.RestoreRequest{LBID: lbId} + enableReq := lb.DisableEnableRequest{LBID: lbId} - _, err := c.DecortAPICall(ctx, "POST", lbRestoreAPI, urlValues) + _, err := c.CloudAPI().LB().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", lbEnableAPI, urlValues) + _, err = c.CloudAPI().LB().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } hasChanged = true case status.Destroying: - return diag.Errorf("The LB is in progress with status: %s", lb.Status) + return diag.Errorf("The LB is in progress with status: %s", lbRec.Status) case status.Destroyed: d.SetId("") return resourceLBCreate(ctx, d, m) @@ -305,12 +281,12 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{} case status.Enabling: case status.Disabling: case status.Disabled: - log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lb.Status) + log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lbRec.Status) case status.Restoring: } if hasChanged { - lb, err = utilityLBCheckPresence(ctx, d, m) + lbRec, err = utilityLBCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) @@ -318,90 +294,96 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{} } if d.HasChange("enable") { - api := lbDisableAPI enable := d.Get("enable").(bool) - if enable { - api = lbEnableAPI + req := lb.DisableEnableRequest{ + LBID: uint64(d.Get("lb_id").(int)), } - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + if enable { + _, err := c.CloudAPI().LB().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + _, err := c.CloudAPI().LB().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("start") { - api := lbStopAPI start := d.Get("start").(bool) + lbId := uint64(d.Get("lb_id").(int)) if start { - api = lbStartAPI - } - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) + req := lb.StartRequest{LBID: lbId} + _, err := c.CloudAPI().LB().Start(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := lb.StopRequest{LBID: lbId} + _, err := c.CloudAPI().LB().Stop(ctx, req) + if err != nil { + return diag.FromErr(err) + } } - - urlValues = &url.Values{} } if d.HasChange("desc") { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("desc", d.Get("desc").(string)) + req := lb.UpdateRequest{ + LBID: uint64(d.Get("lb_id").(int)), + Description: d.Get("desc").(string), + } - _, err := c.DecortAPICall(ctx, "POST", lbUpdateAPI, urlValues) + _, err := c.CloudAPI().LB().Update(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("restart") { restart := d.Get("restart").(bool) if restart { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", lbRestartAPI, urlValues) + req := lb.RestartRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudAPI().LB().Restart(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if d.HasChange("restore") { restore := d.Get("restore").(bool) if restore { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", lbRestoreAPI, urlValues) + req := lb.RestoreRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudAPI().LB().Restore(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if d.HasChange("config_reset") { cfgReset := d.Get("config_reset").(bool) if cfgReset { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", lbConfigResetAPI, urlValues) + req := lb.ConfigResetRequest{ + LBID: uint64(d.Get("lb_id").(int)), + } + + _, err := c.CloudAPI().LB().ConfigReset(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } - //TODO: перенести backend и frontend из ресурсов сюда - return resourceLBRead(ctx, d, m) } diff --git a/internal/service/cloudapi/lb/resource_lb_backend.go b/internal/service/cloudapi/lb/resource_lb_backend.go index c597764..5b63881 100644 --- a/internal/service/cloudapi/lb/resource_lb_backend.go +++ b/internal/service/cloudapi/lb/resource_lb_backend.go @@ -34,7 +34,6 @@ package lb import ( "context" - "net/url" "strconv" "strings" @@ -42,6 +41,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -59,39 +59,40 @@ func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m inte } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("backendName", d.Get("name").(string)) - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req := lb.BackendCreateRequest{} + + req.BackendName = d.Get("name").(string) + req.LBID = uint64(d.Get("lb_id").(int)) if algorithm, ok := d.GetOk("algorithm"); ok { - urlValues.Add("algorithm", algorithm.(string)) + req.Algorithm = algorithm.(string) } if inter, ok := d.GetOk("inter"); ok { - urlValues.Add("inter", strconv.Itoa(inter.(int))) + req.Inter = uint64(inter.(int)) } if downinter, ok := d.GetOk("downinter"); ok { - urlValues.Add("downinter", strconv.Itoa(downinter.(int))) + req.DownInter = uint64(downinter.(int)) } if rise, ok := d.GetOk("rise"); ok { - urlValues.Add("rise", strconv.Itoa(rise.(int))) + req.Rise = uint64(rise.(int)) } if fall, ok := d.GetOk("fall"); ok { - urlValues.Add("fall", strconv.Itoa(fall.(int))) + req.Fall = uint64(fall.(int)) } if slowstart, ok := d.GetOk("slowstart"); ok { - urlValues.Add("slowstart", strconv.Itoa(slowstart.(int))) + req.SlowStart = uint64(slowstart.(int)) } if maxconn, ok := d.GetOk("maxconn"); ok { - urlValues.Add("maxconn", strconv.Itoa(maxconn.(int))) + req.MaxConn = uint64(maxconn.(int)) } if maxqueue, ok := d.GetOk("maxqueue"); ok { - urlValues.Add("maxqueue", strconv.Itoa(maxqueue.(int))) + req.MaxQueue = uint64(maxqueue.(int)) } if weight, ok := d.GetOk("weight"); ok { - urlValues.Add("weight", strconv.Itoa(weight.(int))) + req.Weight = uint64(weight.(int)) } - _, err = c.DecortAPICall(ctx, "POST", lbBackendCreateAPI, urlValues) + _, err = c.CloudAPI().LB().BackendCreate(ctx, req) if err != nil { return diag.FromErr(err) } @@ -103,12 +104,7 @@ func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m inte return diag.FromErr(err) } - diagnostics := resourceLBBackendRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceLBBackendRead(ctx, d, m) } func resourceLBBackendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -122,19 +118,7 @@ func resourceLBBackendRead(ctx context.Context, d *schema.ResourceData, m interf lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) - d.Set("lb_id", lbId) - d.Set("name", b.Name) - d.Set("algorithm", b.Algorithm) - d.Set("guid", b.GUID) - d.Set("downinter", b.ServerDefaultSettings.DownInter) - d.Set("fall", b.ServerDefaultSettings.Fall) - d.Set("inter", b.ServerDefaultSettings.Inter) - d.Set("maxconn", b.ServerDefaultSettings.MaxConn) - d.Set("maxqueue", b.ServerDefaultSettings.MaxQueue) - d.Set("rise", b.ServerDefaultSettings.Rise) - d.Set("slowstart", b.ServerDefaultSettings.SlowStart) - d.Set("weight", b.ServerDefaultSettings.Weight) - d.Set("servers", flattenServers(b.Servers)) + flattenResourceLBBackend(d, b, lbId) return nil } @@ -142,23 +126,22 @@ func resourceLBBackendRead(ctx context.Context, d *schema.ResourceData, m interf func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBBackendDelete") - lb, err := utilityLBBackendCheckPresence(ctx, d, m) - if lb == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityLBBackendCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("backendName", d.Get("name").(string)) + req := lb.BackendDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + } - _, err = c.DecortAPICall(ctx, "POST", lbBackendDeleteAPI, urlValues) + _, err = c.CloudAPI().LB().BackendDelete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil @@ -167,7 +150,6 @@ func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m inte func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBBackendEdit") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} haveLBID, err := existLBID(ctx, d, m) if err != nil { @@ -178,38 +160,40 @@ func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m inte return diag.Errorf("resourceLBBackendUpdate: can't update LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) } - urlValues.Add("backendName", d.Get("name").(string)) - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req := lb.BackendUpdateRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + } if d.HasChange("algorithm") { - urlValues.Add("algorithm", d.Get("algorithm").(string)) + req.Algorithm = d.Get("algorithm").(string) } if d.HasChange("inter") { - urlValues.Add("inter", strconv.Itoa(d.Get("inter").(int))) + req.Inter = uint64(d.Get("inter").(int)) } if d.HasChange("downinter") { - urlValues.Add("downinter", strconv.Itoa(d.Get("downinter").(int))) + req.DownInter = uint64(d.Get("downinter").(int)) } if d.HasChange("rise") { - urlValues.Add("rise", strconv.Itoa(d.Get("rise").(int))) + req.Rise = uint64(d.Get("rise").(int)) } if d.HasChange("fall") { - urlValues.Add("fall", strconv.Itoa(d.Get("fall").(int))) + req.Fall = uint64(d.Get("fall").(int)) } if d.HasChange("slowstart") { - urlValues.Add("slowstart", strconv.Itoa(d.Get("slowstart").(int))) + req.SlowStart = uint64(d.Get("slowstart").(int)) } if d.HasChange("maxconn") { - urlValues.Add("maxconn", strconv.Itoa(d.Get("maxconn").(int))) + req.MaxConn = uint64(d.Get("maxconn").(int)) } if d.HasChange("maxqueue") { - urlValues.Add("maxqueue", strconv.Itoa(d.Get("maxqueue").(int))) + req.MaxQueue = uint64(d.Get("maxqueue").(int)) } if d.HasChange("weight") { - urlValues.Add("weight", strconv.Itoa(d.Get("weight").(int))) + req.Weight = uint64(d.Get("weight").(int)) } - _, err = c.DecortAPICall(ctx, "POST", lbBackendUpdateAPI, urlValues) + _, err = c.CloudAPI().LB().BackendUpdate(ctx, req) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudapi/lb/resource_lb_backend_server.go b/internal/service/cloudapi/lb/resource_lb_backend_server.go index 8056626..c325ec5 100644 --- a/internal/service/cloudapi/lb/resource_lb_backend_server.go +++ b/internal/service/cloudapi/lb/resource_lb_backend_server.go @@ -34,7 +34,6 @@ package lb import ( "context" - "net/url" "strconv" "strings" @@ -42,6 +41,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -59,43 +59,44 @@ func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData, } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("backendName", d.Get("backend_name").(string)) - urlValues.Add("serverName", d.Get("name").(string)) - urlValues.Add("address", d.Get("address").(string)) - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("port", strconv.Itoa(d.Get("port").(int))) + req := lb.BackendServerAddRequest{ + BackendName: d.Get("backend_name").(string), + ServerName: d.Get("name").(string), + Address: d.Get("address").(string), + LBID: uint64(d.Get("lb_id").(int)), + Port: uint64(d.Get("port").(int)), + } if check, ok := d.GetOk("check"); ok { - urlValues.Add("check", check.(string)) + req.Check = check.(string) } if inter, ok := d.GetOk("inter"); ok { - urlValues.Add("inter", strconv.Itoa(inter.(int))) + req.Inter = uint64(inter.(int)) } if downinter, ok := d.GetOk("downinter"); ok { - urlValues.Add("downinter", strconv.Itoa(downinter.(int))) + req.DownInter = uint64(downinter.(int)) } if rise, ok := d.GetOk("rise"); ok { - urlValues.Add("rise", strconv.Itoa(rise.(int))) + req.Rise = uint64(rise.(int)) } if fall, ok := d.GetOk("fall"); ok { - urlValues.Add("fall", strconv.Itoa(fall.(int))) + req.Fall = uint64(fall.(int)) } if slowstart, ok := d.GetOk("slowstart"); ok { - urlValues.Add("slowstart", strconv.Itoa(slowstart.(int))) + req.SlowStart = uint64(slowstart.(int)) } if maxconn, ok := d.GetOk("maxconn"); ok { - urlValues.Add("maxconn", strconv.Itoa(maxconn.(int))) + req.MaxConn = uint64(maxconn.(int)) } if maxqueue, ok := d.GetOk("maxqueue"); ok { - urlValues.Add("maxqueue", strconv.Itoa(maxqueue.(int))) + req.MaxQueue = uint64(maxqueue.(int)) } if weight, ok := d.GetOk("weight"); ok { - urlValues.Add("weight", strconv.Itoa(weight.(int))) + req.Weight = uint64(weight.(int)) } - _, err = c.DecortAPICall(ctx, "POST", lbBackendServerAddAPI, urlValues) + _, err = c.CloudAPI().LB().BackendServerAdd(ctx, req) if err != nil { return diag.FromErr(err) } @@ -107,19 +108,14 @@ func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData, return diag.FromErr(err) } - diagnostics := resourceLBBackendServerRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceLBBackendServerRead(ctx, d, m) } func resourceLBBackendServerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBBackendServerRead") s, err := utilityLBBackendServerCheckPresence(ctx, d, m) - if s == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } @@ -127,21 +123,7 @@ func resourceLBBackendServerRead(ctx context.Context, d *schema.ResourceData, m lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) backendName := strings.Split(d.Id(), "#")[1] - d.Set("lb_id", lbId) - d.Set("backend_name", backendName) - d.Set("name", s.Name) - d.Set("port", s.Port) - d.Set("address", s.Address) - d.Set("check", s.Check) - d.Set("guid", s.GUID) - d.Set("downinter", s.ServerSettings.DownInter) - d.Set("fall", s.ServerSettings.Fall) - d.Set("inter", s.ServerSettings.Inter) - d.Set("maxconn", s.ServerSettings.MaxConn) - d.Set("maxqueue", s.ServerSettings.MaxQueue) - d.Set("rise", s.ServerSettings.Rise) - d.Set("slowstart", s.ServerSettings.SlowStart) - d.Set("weight", s.ServerSettings.Weight) + flattenResourceLBBackendServer(d, s, lbId, backendName) return nil } @@ -149,21 +131,19 @@ func resourceLBBackendServerRead(ctx context.Context, d *schema.ResourceData, m func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBBackendServerDelete") - lb, err := utilityLBBackendServerCheckPresence(ctx, d, m) - if lb == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityLBBackendServerCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("serverName", d.Get("name").(string)) - urlValues.Add("backendName", d.Get("backend_name").(string)) + req := lb.BackendServerDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + BackendName: d.Get("name").(string), + ServerName: d.Get("backend_name").(string), + } - _, err = c.DecortAPICall(ctx, "POST", lbBackendServerDeleteAPI, urlValues) + _, err = c.CloudAPI().LB().BackendServerDelete(ctx, req) if err != nil { return diag.FromErr(err) } @@ -175,7 +155,6 @@ func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData, func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBBackendServerEdit") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} haveLBID, err := existLBID(ctx, d, m) if err != nil { @@ -186,41 +165,43 @@ func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData, return diag.Errorf("resourceLBBackendServerUpdate: can't update LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) } - urlValues.Add("backendName", d.Get("backend_name").(string)) - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("serverName", d.Get("name").(string)) - urlValues.Add("address", d.Get("address").(string)) - urlValues.Add("port", strconv.Itoa(d.Get("port").(int))) + req := lb.BackendServerUpdateRequest{ + BackendName: d.Get("backend_name").(string), + LBID: uint64(d.Get("lb_id").(int)), + ServerName: d.Get("name").(string), + Address: d.Get("address").(string), + Port: uint64(d.Get("port").(int)), + } if d.HasChange("check") { - urlValues.Add("check", d.Get("check").(string)) + req.Check = d.Get("check").(string) } if d.HasChange("inter") { - urlValues.Add("inter", strconv.Itoa(d.Get("inter").(int))) + req.Inter = uint64(d.Get("inter").(int)) } if d.HasChange("downinter") { - urlValues.Add("downinter", strconv.Itoa(d.Get("downinter").(int))) + req.DownInter = uint64(d.Get("downinter").(int)) } if d.HasChange("rise") { - urlValues.Add("rise", strconv.Itoa(d.Get("rise").(int))) + req.Rise = uint64(d.Get("rise").(int)) } if d.HasChange("fall") { - urlValues.Add("fall", strconv.Itoa(d.Get("fall").(int))) + req.Fall = uint64(d.Get("fall").(int)) } if d.HasChange("slowstart") { - urlValues.Add("slowstart", strconv.Itoa(d.Get("slowstart").(int))) + req.SlowStart = uint64(d.Get("slowstart").(int)) } if d.HasChange("maxconn") { - urlValues.Add("maxconn", strconv.Itoa(d.Get("maxconn").(int))) + req.MaxConn = uint64(d.Get("maxconn").(int)) } if d.HasChange("maxqueue") { - urlValues.Add("maxqueue", strconv.Itoa(d.Get("maxqueue").(int))) + req.MaxQueue = uint64(d.Get("maxqueue").(int)) } if d.HasChange("weight") { - urlValues.Add("weight", strconv.Itoa(d.Get("weight").(int))) + req.Weight = uint64(d.Get("weight").(int)) } - _, err = c.DecortAPICall(ctx, "POST", lbBackendServerUpdateAPI, urlValues) + _, err = c.CloudAPI().LB().BackendServerUpdate(ctx, req) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudapi/lb/resource_lb_frontend.go b/internal/service/cloudapi/lb/resource_lb_frontend.go index cbbb749..0ddf525 100644 --- a/internal/service/cloudapi/lb/resource_lb_frontend.go +++ b/internal/service/cloudapi/lb/resource_lb_frontend.go @@ -34,13 +34,13 @@ package lb import ( "context" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -58,12 +58,13 @@ func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m int } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("backendName", d.Get("backend_name").(string)) - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("frontendName", d.Get("name").(string)) + req := lb.FrontendCreateRequest{ + BackendName: d.Get("backend_name").(string), + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("name").(string), + } - _, err = c.DecortAPICall(ctx, "POST", lbFrontendCreateAPI, urlValues) + _, err = c.CloudAPI().LB().FrontendCreate(ctx, req) if err != nil { return diag.FromErr(err) } @@ -75,29 +76,21 @@ func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m int return diag.FromErr(err) } - diagnostics := resourceLBFrontendRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceLBFrontendRead(ctx, d, m) } func resourceLBFrontendRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBFrontendRead") f, err := utilityLBFrontendCheckPresence(ctx, d, m) - if f == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) - d.Set("lb_id", lbId) - d.Set("backend_name", f.Backend) - d.Set("name", f.Name) - d.Set("guid", f.GUID) - d.Set("bindings", flattendBindings(f.Bindings)) + + flattenLBFrontend(d, f, lbId) return nil } @@ -105,23 +98,22 @@ func resourceLBFrontendRead(ctx context.Context, d *schema.ResourceData, m inter func resourceLBFrontendDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBFrontendDelete") - lb, err := utilityLBFrontendCheckPresence(ctx, d, m) - if lb == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityLBFrontendCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("frontendName", d.Get("name").(string)) + req := lb.FrontendDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("name").(string), + } - _, err = c.DecortAPICall(ctx, "POST", lbFrontendDeleteAPI, urlValues) + _, err = c.CloudAPI().LB().FrontendDelete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil diff --git a/internal/service/cloudapi/lb/resource_lb_frontend_bind.go b/internal/service/cloudapi/lb/resource_lb_frontend_bind.go index 7adcc85..9d83b5d 100644 --- a/internal/service/cloudapi/lb/resource_lb_frontend_bind.go +++ b/internal/service/cloudapi/lb/resource_lb_frontend_bind.go @@ -34,13 +34,13 @@ package lb import ( "context" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -58,14 +58,15 @@ func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("frontendName", d.Get("frontend_name").(string)) - urlValues.Add("bindingName", d.Get("name").(string)) - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("bindingAddress", d.Get("address").(string)) - urlValues.Add("bindingPort", strconv.Itoa(d.Get("port").(int))) - - _, err = c.DecortAPICall(ctx, "POST", lbFrontendBindAPI, urlValues) + req := lb.FrontendBindRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + BindingAddress: d.Get("address").(string), + BindingPort: uint64(d.Get("port").(int)), + } + + _, err = c.CloudAPI().LB().FrontendBind(ctx, req) if err != nil { return diag.FromErr(err) } @@ -77,19 +78,14 @@ func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m return diag.FromErr(err) } - diagnostics := resourceLBFrontendBindRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceLBFrontendBindRead(ctx, d, m) } func resourceLBFrontendBindRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBFrontendBindRead") b, err := utilityLBFrontendBindCheckPresence(ctx, d, m) - if b == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } @@ -97,12 +93,7 @@ func resourceLBFrontendBindRead(ctx context.Context, d *schema.ResourceData, m i lbId, _ := strconv.ParseInt(strings.Split(d.Id(), "#")[0], 10, 32) frontendName := strings.Split(d.Id(), "#")[1] - d.Set("lb_id", lbId) - d.Set("frontend_name", frontendName) - d.Set("name", b.Name) - d.Set("address", b.Address) - d.Set("guid", b.GUID) - d.Set("port", b.Port) + flattenLBFrontendBind(d, b, lbId, frontendName) return nil } @@ -110,24 +101,23 @@ func resourceLBFrontendBindRead(ctx context.Context, d *schema.ResourceData, m i func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBFrontendBindDelete") - b, err := utilityLBFrontendBindCheckPresence(ctx, d, m) - if b == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityLBFrontendBindCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) - urlValues.Add("bindingName", d.Get("name").(string)) - urlValues.Add("frontendName", d.Get("frontend_name").(string)) + req := lb.FrontendBindDeleteRequest{ + LBID: uint64(d.Get("lb_id").(int)), + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + } - _, err = c.DecortAPICall(ctx, "POST", lbFrontendBindDeleteAPI, urlValues) + _, err = c.CloudAPI().LB().FrontendBindDelete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil @@ -136,7 +126,6 @@ func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceLBFrontendBindEdit") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} haveLBID, err := existLBID(ctx, d, m) if err != nil { @@ -147,19 +136,21 @@ func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m return diag.Errorf("resourceLBFrontendBindUpdate: can't update LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int)) } - urlValues.Add("frontendName", d.Get("frontend_name").(string)) - urlValues.Add("bindingName", d.Get("name").(string)) - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req := lb.FrontendBindUpdateRequest{ + FrontendName: d.Get("frontend_name").(string), + BindingName: d.Get("name").(string), + LBID: uint64(d.Get("lb_id").(int)), + } if d.HasChange("address") { - urlValues.Add("bindingAddress", d.Get("address").(string)) + req.BindingAddress = d.Get("address").(string) } if d.HasChange("port") { - urlValues.Add("bindingPort", strconv.Itoa(d.Get("port").(int))) + req.BindingPort = uint64(d.Get("port").(int)) } - _, err = c.DecortAPICall(ctx, "POST", lbFrontendBindUpdateAPI, urlValues) + _, err = c.CloudAPI().LB().FrontendBindUpdate(ctx, req) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudapi/lb/utility_lb.go b/internal/service/cloudapi/lb/utility_lb.go index 71f041e..d1d00ca 100644 --- a/internal/service/cloudapi/lb/utility_lb.go +++ b/internal/service/cloudapi/lb/utility_lb.go @@ -34,38 +34,28 @@ package lb import ( "context" - "encoding/json" - "fmt" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityLBCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*LoadBalancer, error) { +func utilityLBCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.RecordLB, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := lb.GetRequest{} if (d.Get("lb_id").(int)) != 0 { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req.LBID = uint64(d.Get("lb_id").(int)) } else { - urlValues.Add("lbId", d.Id()) + lbId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.LBID = lbId } - resp, err := c.DecortAPICall(ctx, "POST", lbGetAPI, urlValues) + lb, err := c.CloudAPI().LB().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - - lb := &LoadBalancer{} - if err := json.Unmarshal([]byte(resp), lb); err != nil { - return nil, fmt.Errorf("can not unmarshall data to lb: %s %+v", resp, lb) - } - return lb, nil } diff --git a/internal/service/cloudapi/lb/utility_lb_backend.go b/internal/service/cloudapi/lb/utility_lb_backend.go index 7cc936f..c935e50 100644 --- a/internal/service/cloudapi/lb/utility_lb_backend.go +++ b/internal/service/cloudapi/lb/utility_lb_backend.go @@ -34,44 +34,34 @@ package lb import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityLBBackendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Backend, error) { +func utilityLBBackendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemBackend, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - + req := lb.GetRequest{} bName := d.Get("name").(string) if (d.Get("lb_id").(int)) != 0 { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req.LBID = uint64(d.Get("lb_id").(int)) } else { parameters := strings.Split(d.Id(), "#") - urlValues.Add("lbId", parameters[0]) + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId bName = parameters[1] } - resp, err := c.DecortAPICall(ctx, "POST", lbGetAPI, urlValues) + lb, err := c.CloudAPI().LB().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - - lb := &LoadBalancer{} - if err := json.Unmarshal([]byte(resp), lb); err != nil { - return nil, fmt.Errorf("can not unmarshall data to lb: %s %+v", resp, lb) - } - backends := lb.Backends for _, b := range backends { if b.Name == bName { diff --git a/internal/service/cloudapi/lb/utility_lb_backend_server.go b/internal/service/cloudapi/lb/utility_lb_backend_server.go index 91c71d9..227d955 100644 --- a/internal/service/cloudapi/lb/utility_lb_backend_server.go +++ b/internal/service/cloudapi/lb/utility_lb_backend_server.go @@ -34,56 +34,49 @@ package lb import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityLBBackendServerCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Server, error) { +func utilityLBBackendServerCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemServer, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := lb.GetRequest{} bName := d.Get("backend_name").(string) sName := d.Get("name").(string) if (d.Get("lb_id").(int)) != 0 { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req.LBID = uint64(d.Get("lb_id").(int)) } else { parameters := strings.Split(d.Id(), "#") - urlValues.Add("lbId", parameters[0]) + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + req.LBID = lbId + bName = parameters[1] sName = parameters[2] } - resp, err := c.DecortAPICall(ctx, "POST", lbGetAPI, urlValues) + foundLB, err := c.CloudAPI().LB().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - - lb := &LoadBalancer{} - if err := json.Unmarshal([]byte(resp), lb); err != nil { - return nil, fmt.Errorf("can not unmarshall data to lb: %s %+v", resp, lb) - } - - backend := &Backend{} - backends := lb.Backends + backend := &lb.ItemBackend{} + backends := foundLB.Backends for i, b := range backends { if b.Name == bName { backend = &backends[i] break } } + if backend.Name == "" { - return nil, fmt.Errorf("can not find backend with name: %s for lb: %d", bName, lb.ID) + return nil, fmt.Errorf("can not find backend with name: %s for lb: %d", bName, foundLB.ID) } for _, s := range backend.Servers { @@ -92,5 +85,5 @@ func utilityLBBackendServerCheckPresence(ctx context.Context, d *schema.Resource } } - return nil, fmt.Errorf("can not find server with name: %s for backend: %s for lb: %d", sName, bName, lb.ID) + return nil, fmt.Errorf("can not find server with name: %s for backend: %s for lb: %d", sName, bName, foundLB.ID) } diff --git a/internal/service/cloudapi/lb/utility_lb_frontend.go b/internal/service/cloudapi/lb/utility_lb_frontend.go index b7e80c2..e060ca7 100644 --- a/internal/service/cloudapi/lb/utility_lb_frontend.go +++ b/internal/service/cloudapi/lb/utility_lb_frontend.go @@ -34,50 +34,42 @@ package lb import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityLBFrontendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Frontend, error) { +func utilityLBFrontendCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemFrontend, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := lb.GetRequest{} fName := d.Get("name").(string) if (d.Get("lb_id").(int)) != 0 { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req.LBID = uint64(d.Get("lb_id").(int)) } else { parameters := strings.Split(d.Id(), "#") - urlValues.Add("lbId", parameters[0]) + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + + req.LBID = lbId fName = parameters[1] } - resp, err := c.DecortAPICall(ctx, "POST", lbGetAPI, urlValues) + foundLB, err := c.CloudAPI().LB().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - - lb := &LoadBalancer{} - if err := json.Unmarshal([]byte(resp), lb); err != nil { - return nil, fmt.Errorf("can not unmarshall data to lb: %s %+v", resp, lb) - } - - frontends := lb.Frontends + frontends := foundLB.Frontends for _, f := range frontends { if f.Name == fName { return &f, nil } } - return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, lb.ID) + return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, foundLB.ID) } diff --git a/internal/service/cloudapi/lb/utility_lb_frontend_bind.go b/internal/service/cloudapi/lb/utility_lb_frontend_bind.go index b4966d6..3af1cd8 100644 --- a/internal/service/cloudapi/lb/utility_lb_frontend_bind.go +++ b/internal/service/cloudapi/lb/utility_lb_frontend_bind.go @@ -34,48 +34,40 @@ package lb import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityLBFrontendBindCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Binding, error) { +func utilityLBFrontendBindCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*lb.ItemBinding, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := lb.GetRequest{} fName := d.Get("frontend_name").(string) bName := d.Get("name").(string) if (d.Get("lb_id").(int)) != 0 { - urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int))) + req.LBID = uint64(d.Get("lb_id").(int)) } else { parameters := strings.Split(d.Id(), "#") - urlValues.Add("lbId", parameters[0]) + lbId, _ := strconv.ParseUint(parameters[0], 10, 64) + + req.LBID = lbId fName = parameters[1] bName = parameters[2] } - resp, err := c.DecortAPICall(ctx, "POST", lbGetAPI, urlValues) + foundLB, err := c.CloudAPI().LB().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - - lb := &LoadBalancer{} - if err := json.Unmarshal([]byte(resp), lb); err != nil { - return nil, fmt.Errorf("can not unmarshall data to lb: %s %+v", resp, lb) - } - - frontend := &Frontend{} - frontends := lb.Frontends + frontend := &lb.ItemFrontend{} + frontends := foundLB.Frontends for i, f := range frontends { if f.Name == fName { frontend = &frontends[i] @@ -83,7 +75,7 @@ func utilityLBFrontendBindCheckPresence(ctx context.Context, d *schema.ResourceD } } if frontend.Name == "" { - return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, lb.ID) + return nil, fmt.Errorf("can not find frontend with name: %s for lb: %d", fName, foundLB.ID) } for _, b := range frontend.Bindings { @@ -92,5 +84,5 @@ func utilityLBFrontendBindCheckPresence(ctx context.Context, d *schema.ResourceD } } - return nil, fmt.Errorf("can not find bind with name: %s for frontend: %s for lb: %d", bName, fName, lb.ID) + return nil, fmt.Errorf("can not find bind with name: %s for frontend: %s for lb: %d", bName, fName, foundLB.ID) } diff --git a/internal/service/cloudapi/lb/utility_lb_list.go b/internal/service/cloudapi/lb/utility_lb_list.go index 1fa9a4b..dcee79d 100644 --- a/internal/service/cloudapi/lb/utility_lb_list.go +++ b/internal/service/cloudapi/lb/utility_lb_list.go @@ -34,39 +34,31 @@ package lb import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityLBListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (LBList, error) { - lbList := LBList{} +func utilityLBListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (lb.ListLB, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := lb.ListRequest{} if includedeleted, ok := d.GetOk("includedeleted"); ok { - urlValues.Add("includedeleted", strconv.FormatBool((includedeleted.(bool)))) + req.IncludeDeleted = includedeleted.(bool) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityLBListCheckPresence: load lb list") - lbListRaw, err := c.DecortAPICall(ctx, "POST", lbListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(lbListRaw), &lbList) + lbList, err := c.CloudAPI().LB().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/lb/utility_lb_list_deleted.go b/internal/service/cloudapi/lb/utility_lb_list_deleted.go index a52e740..d7eced9 100644 --- a/internal/service/cloudapi/lb/utility_lb_list_deleted.go +++ b/internal/service/cloudapi/lb/utility_lb_list_deleted.go @@ -34,35 +34,27 @@ package lb import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/lb" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityLBListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (LBList, error) { - lbList := LBList{} +func utilityLBListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (lb.ListLB, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := lb.ListDeletedRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityLBListDeletedCheckPresence: load lb list") - lbListRaw, err := c.DecortAPICall(ctx, "POST", lbListDeletedAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(lbListRaw), &lbList) + lbList, err := c.CloudAPI().LB().ListDeleted(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/locations/api.go b/internal/service/cloudapi/locations/api.go deleted file mode 100644 index bda77e1..0000000 --- a/internal/service/cloudapi/locations/api.go +++ /dev/null @@ -1,24 +0,0 @@ -package locations - -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -const locationsListAPI = "/restmachine/cloudapi/locations/list" -const locationURLAPI = "/restmachine/cloudapi/locations/getUrl" diff --git a/internal/service/cloudapi/locations/data_source_locations_list.go b/internal/service/cloudapi/locations/data_source_locations_list.go index c329f4f..a4ccade 100644 --- a/internal/service/cloudapi/locations/data_source_locations_list.go +++ b/internal/service/cloudapi/locations/data_source_locations_list.go @@ -38,20 +38,21 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) -func flattenLocationsList(ll LocationsList) []map[string]interface{} { +func flattenLocationsList(ll locations.ListLocations) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, l := range ll { temp := map[string]interface{}{ "ckey": l.CKey, "meta": flattens.FlattenMeta(l.Meta), "flag": l.Flag, - "gid": l.GridID, - "guid": l.Guid, - "id": l.Id, + "gid": l.GID, + "guid": l.GUID, + "id": l.ID, "location_code": l.LocationCode, "name": l.Name, } @@ -64,7 +65,6 @@ func flattenLocationsList(ll LocationsList) []map[string]interface{} { func dataSourceLocationsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { locations, err := utilityLocationsListCheckPresence(ctx, d, m) if err != nil { - return diag.FromErr(err) } diff --git a/internal/service/cloudapi/locations/data_source_locations_url.go b/internal/service/cloudapi/locations/data_source_locations_url.go index 3e5718e..ee16668 100644 --- a/internal/service/cloudapi/locations/data_source_locations_url.go +++ b/internal/service/cloudapi/locations/data_source_locations_url.go @@ -34,6 +34,7 @@ package locations import ( "context" + "strings" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -50,6 +51,8 @@ func dataSourceLocationUrlRead(ctx context.Context, d *schema.ResourceData, m in id := uuid.New() d.SetId(id.String()) + url = strings.ReplaceAll(url, "\\", "") + url = strings.ReplaceAll(url, "\"", "") d.Set("url", url) return nil diff --git a/internal/service/cloudapi/locations/utility_location_url.go b/internal/service/cloudapi/locations/utility_location_url.go index 735d5b6..bec3226 100644 --- a/internal/service/cloudapi/locations/utility_location_url.go +++ b/internal/service/cloudapi/locations/utility_location_url.go @@ -34,8 +34,6 @@ package locations import ( "context" - "encoding/json" - "net/url" log "github.com/sirupsen/logrus" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" @@ -45,16 +43,10 @@ func utilityLocationUrlCheckPresence(ctx context.Context, m interface{}) (string c := m.(*controller.ControllerCfg) log.Debugf("utilityLocationUrlCheckPresence: load locations list") - locationUrl, err := c.DecortAPICall(ctx, "POST", locationURLAPI, &url.Values{}) + locationUrl, err := c.CloudAPI().Locations().GetURL(ctx) if err != nil { return "", err } - location := new(string) - err = json.Unmarshal([]byte(locationUrl), location) - if err != nil { - return "", err - } - - return *location, nil + return locationUrl, nil } diff --git a/internal/service/cloudapi/locations/utility_locations_list.go b/internal/service/cloudapi/locations/utility_locations_list.go index d583b63..b0385cc 100644 --- a/internal/service/cloudapi/locations/utility_locations_list.go +++ b/internal/service/cloudapi/locations/utility_locations_list.go @@ -34,35 +34,27 @@ package locations import ( "context" - "encoding/json" - "net/url" - "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityLocationsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (LocationsList, error) { - locationsList := LocationsList{} +func utilityLocationsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (locations.ListLocations, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := locations.ListRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityLocationsListCheckPresence: load locations list") - locationsListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(locationsListRaw), &locationsList) + locationsList, err := c.CloudAPI().Locations().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/pfw/api.go b/internal/service/cloudapi/pfw/api.go deleted file mode 100644 index e1591f9..0000000 --- a/internal/service/cloudapi/pfw/api.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package pfw - -const ComputePfwListAPI = "/restmachine/cloudapi/compute/pfwList" -const ComputePfwAddAPI = "/restmachine/cloudapi/compute/pfwAdd" -const ComputePfwDelAPI = "/restmachine/cloudapi/compute/pfwDel" diff --git a/internal/service/cloudapi/pfw/flattens.go b/internal/service/cloudapi/pfw/flattens.go new file mode 100644 index 0000000..55e2b65 --- /dev/null +++ b/internal/service/cloudapi/pfw/flattens.go @@ -0,0 +1,15 @@ +package pfw + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" +) + +func flattenPFW(d *schema.ResourceData, pfw *compute.ItemPFW) { + d.Set("compute_id", pfw.VMID) + d.Set("public_port_start", pfw.PublicPortStart) + d.Set("public_port_end", pfw.PublicPortEnd) + d.Set("local_ip", pfw.LocalIP) + d.Set("local_base_port", pfw.LocalPort) + d.Set("proto", pfw.Protocol) +} diff --git a/internal/service/cloudapi/pfw/models.go b/internal/service/cloudapi/pfw/models.go deleted file mode 100644 index b3bf93e..0000000 --- a/internal/service/cloudapi/pfw/models.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package pfw - -type PfwRecord struct { - ID int `json:"id"` - LocalIP string `json:"localIp"` - LocalPort int `json:"localPort"` - Protocol string `json:"protocol"` - PublicPortEnd int `json:"publicPortEnd"` - PublicPortStart int `json:"publicPortStart"` - ComputeID int `json:"vmId"` -} - -type ComputePfwListResp []PfwRecord diff --git a/internal/service/cloudapi/pfw/resource_pfw.go b/internal/service/cloudapi/pfw/resource_pfw.go index 981f962..99d2fd8 100644 --- a/internal/service/cloudapi/pfw/resource_pfw.go +++ b/internal/service/cloudapi/pfw/resource_pfw.go @@ -35,13 +35,12 @@ package pfw import ( "context" "fmt" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -50,22 +49,23 @@ func resourcePfwCreate(ctx context.Context, d *schema.ResourceData, m interface{ log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("publicPortStart", strconv.Itoa(d.Get("public_port_start").(int))) - urlValues.Add("localBasePort", strconv.Itoa(d.Get("local_base_port").(int))) - urlValues.Add("proto", d.Get("proto").(string)) + req := compute.PFWAddRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + PublicPortStart: uint64(d.Get("public_port_start").(int)), + LocalBasePort: uint64(d.Get("local_base_port").(int)), + Proto: d.Get("proto").(string), + } if portEnd, ok := d.GetOk("public_port_end"); ok { - urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int))) + req.PublicPortEnd = uint64(portEnd.(int)) } - pfwId, err := c.DecortAPICall(ctx, "POST", ComputePfwAddAPI, urlValues) + pfwId, err := c.CloudAPI().Compute().PFWAdd(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(fmt.Sprintf("%d-%s", d.Get("compute_id").(int), pfwId)) + d.SetId(fmt.Sprintf("%d-%d", d.Get("compute_id").(int), pfwId)) pfw, err := utilityPfwCheckPresence(ctx, d, m) if err != nil { @@ -77,24 +77,19 @@ func resourcePfwCreate(ctx context.Context, d *schema.ResourceData, m interface{ d.Set("public_port_end", pfw.PublicPortEnd) } - return nil + return resourcePfwRead(ctx, d, m) } func resourcePfwRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourcePfwRead: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id()) pfw, err := utilityPfwCheckPresence(ctx, d, m) - if pfw == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } - d.Set("compute_id", pfw.ComputeID) - d.Set("public_port_start", pfw.PublicPortStart) - d.Set("public_port_end", pfw.PublicPortEnd) - d.Set("local_ip", pfw.LocalIP) - d.Set("local_base_port", pfw.LocalPort) - d.Set("proto", pfw.Protocol) + flattenPFW(d, pfw) return nil } @@ -103,23 +98,23 @@ func resourcePfwDelete(ctx context.Context, d *schema.ResourceData, m interface{ log.Debugf("resourcePfwDelete: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id()) pfw, err := utilityPfwCheckPresence(ctx, d, m) - if pfw == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("ruleId", strconv.Itoa(pfw.ID)) + req := compute.PFWDelRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + PFWID: pfw.ID, + } - _, err = c.DecortAPICall(ctx, "POST", ComputePfwDelAPI, urlValues) + _, err = c.CloudAPI().Compute().PFWDel(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") + return nil } diff --git a/internal/service/cloudapi/pfw/utility_pfw.go b/internal/service/cloudapi/pfw/utility_pfw.go index 88f113b..71a4b60 100644 --- a/internal/service/cloudapi/pfw/utility_pfw.go +++ b/internal/service/cloudapi/pfw/utility_pfw.go @@ -34,42 +34,33 @@ package pfw import ( "context" - "encoding/json" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*PfwRecord, error) { +func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemPFW, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := compute.PFWListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - resp, err := c.DecortAPICall(ctx, "POST", ComputePfwListAPI, urlValues) + pfws, err := c.CloudAPI().Compute().PFWList(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - idS := strings.Split(d.Id(), "-")[1] id, err := strconv.Atoi(idS) if err != nil { return nil, err } - var pfws []PfwRecord - if err := json.Unmarshal([]byte(resp), &pfws); err != nil { - return nil, err - } - for _, pfw := range pfws { - if pfw.ID == id { + if pfw.ID == uint64(id) { return &pfw, nil } } diff --git a/internal/service/cloudapi/rg/api.go b/internal/service/cloudapi/rg/api.go deleted file mode 100644 index dce02ce..0000000 --- a/internal/service/cloudapi/rg/api.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package rg - -const ( - ResgroupCreateAPI = "/restmachine/cloudapi/rg/create" - ResgroupUpdateAPI = "/restmachine/cloudapi/rg/update" - ResgroupListAPI = "/restmachine/cloudapi/rg/list" - ResgroupListDeletedAPI = "/restmachine/cloudapi/rg/listDeleted" - ResgroupListPfwAPI = "/restmachine/cloudapi/rg/listPFW" - ResgroupGetAPI = "/restmachine/cloudapi/rg/get" - ResgroupListVinsAPI = "/restmachine/cloudapi/rg/listVins" - ResgroupListLbAPI = "/restmachine/cloudapi/rg/listLb" - ResgroupDeleteAPI = "/restmachine/cloudapi/rg/delete" - RgListComputesAPI = "/restmachine/cloudapi/rg/listComputes" - RgAffinityGroupComputesAPI = "/restmachine/cloudapi/rg/affinityGroupComputes" - RgAffinityGroupsGetAPI = "/restmachine/cloudapi/rg/affinityGroupsGet" - RgAffinityGroupsListAPI = "/restmachine/cloudapi/rg/affinityGroupsList" - RgAuditsAPI = "/restmachine/cloudapi/rg/audits" - RgEnableAPI = "/restmachine/cloudapi/rg/enable" - RgDisableAPI = "/restmachine/cloudapi/rg/disable" - ResgroupUsageAPI = "/restmachine/cloudapi/rg/usage" - RgAccessGrantAPI = "/restmachine/cloudapi/rg/accessGrant" - RgAccessRevokeAPI = "/restmachine/cloudapi/rg/accessRevoke" - RgSetDefNetAPI = "/restmachine/cloudapi/rg/setDefNet" - RgRestoreAPI = "/restmachine/cloudapi/rg/restore" -) diff --git a/internal/service/cloudapi/rg/data_source_rg.go b/internal/service/cloudapi/rg/data_source_rg.go index bcaeb28..0cffa9b 100644 --- a/internal/service/cloudapi/rg/data_source_rg.go +++ b/internal/service/cloudapi/rg/data_source_rg.go @@ -384,6 +384,14 @@ func dataSourceRgSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, }, }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, } return res } diff --git a/internal/service/cloudapi/rg/data_source_rg_list.go b/internal/service/cloudapi/rg/data_source_rg_list.go index 780d5d9..a42b5de 100644 --- a/internal/service/cloudapi/rg/data_source_rg_list.go +++ b/internal/service/cloudapi/rg/data_source_rg_list.go @@ -204,6 +204,14 @@ func dataSourceRgListSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, }, }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, "uniq_pools": { Type: schema.TypeList, Computed: true, diff --git a/internal/service/cloudapi/rg/flattens.go b/internal/service/cloudapi/rg/flattens.go index d21273f..0e56a79 100644 --- a/internal/service/cloudapi/rg/flattens.go +++ b/internal/service/cloudapi/rg/flattens.go @@ -34,10 +34,10 @@ package rg import ( "encoding/json" - "fmt" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" ) func flattenAccountSeps(seps map[string]map[string]DiskUsage) []map[string]interface{} { @@ -83,22 +83,10 @@ func flattenRgResources(r Resources) []map[string]interface{} { return res } -func flattenResgroup(d *schema.ResourceData, details RecordResourceGroup) error { - // NOTE: this function modifies ResourceData argument - as such it should never be called - // from resourceRsgroupExists(...) method - // log.Debugf("%s", rg_facts) - //log.Debugf("flattenResgroup: ready to decode response body from API") - //details := ResgroupGetResp{} - //err := json.Unmarshal([]byte(rg_facts), &details) - //if err != nil { - //return err - //} - +func flattenResgroup(d *schema.ResourceData, details rg.RecordResourceGroup) error { log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d", details.Name, details.ID, details.AccountID) - d.SetId(fmt.Sprintf("%d", details.ID)) - d.Set("account_id", details.AccountID) d.Set("gid", details.GID) d.Set("def_net_type", details.DefNetType) @@ -127,11 +115,13 @@ func flattenResgroup(d *schema.ResourceData, details RecordResourceGroup) error d.Set("updated_time", details.UpdatedTime) d.Set("uniq_pools", details.UniqPools) d.Set("vins", details.VINS) + d.Set("cpu_allocation_parameter", details.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", details.CPUAllocationRatio) return nil } -func flattenRgSeps(seps map[string]map[string]DiskUsage) []map[string]interface{} { +func flattenRgSeps(seps map[string]map[string]rg.DiskUsage) []map[string]interface{} { res := make([]map[string]interface{}, 0) for sepKey, sepVal := range seps { SepMap := map[string]interface{}{} @@ -148,7 +138,7 @@ func flattenRgSeps(seps map[string]map[string]DiskUsage) []map[string]interface{ return res } -func flattenResource(resource Resource) []map[string]interface{} { +func flattenResource(resource rg.Resource) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ @@ -167,7 +157,7 @@ func flattenResource(resource Resource) []map[string]interface{} { return res } -func flattenRgResource(itemResource Resources) []map[string]interface{} { +func flattenRgResource(itemResource rg.Resources) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "current": flattenResource(itemResource.Current), @@ -178,7 +168,7 @@ func flattenRgResource(itemResource Resources) []map[string]interface{} { return res } -func flattenRg(d *schema.ResourceData, itemRg RecordResourceGroup) { +func flattenRg(d *schema.ResourceData, itemRg rg.RecordResourceGroup) { d.Set("resources", flattenRgResource(itemRg.Resources)) d.Set("account_id", itemRg.AccountID) d.Set("account_name", itemRg.AccountName) @@ -207,9 +197,11 @@ func flattenRg(d *schema.ResourceData, itemRg RecordResourceGroup) { d.Set("updated_time", itemRg.UpdatedTime) d.Set("uniq_pools", itemRg.UniqPools) d.Set("vins", itemRg.VINS) + d.Set("cpu_allocation_parameter", itemRg.CPUAllocationParameter) + d.Set("cpu_allocation_ratio", itemRg.CPUAllocationRatio) } -func flattenRgAudits(rgAudits ListAudits) []map[string]interface{} { +func flattenRgAudits(rgAudits rg.ListAudits) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rgAudit := range rgAudits { temp := map[string]interface{}{ @@ -226,38 +218,40 @@ func flattenRgAudits(rgAudits ListAudits) []map[string]interface{} { return res } -func flattenRgList(rgl ListResourceGroups) []map[string]interface{} { +func flattenRgList(rgl rg.ListResourceGroups) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rg := range rgl { temp := map[string]interface{}{ - "account_acl": flattenRgAcl(rg.ACL), - "account_id": rg.AccountID, - "account_name": rg.AccountName, - "acl": flattenRgAcl(rg.ACL), - "created_by": rg.CreatedBy, - "created_time": rg.CreatedTime, - "def_net_id": rg.DefNetID, - "def_net_type": rg.DefNetType, - "deleted_by": rg.DeletedBy, - "deleted_time": rg.DeletedTime, - "desc": rg.Description, - "dirty": rg.Dirty, - "gid": rg.GID, - "guid": rg.GUID, - "rg_id": rg.ID, - "lock_status": rg.LockStatus, - "milestones": rg.Milestones, - "name": rg.Name, - "register_computes": rg.RegisterComputes, - "resource_limits": flattenRgResourceLimits(rg.ResourceLimits), - "secret": rg.Secret, - "status": rg.Status, - "updated_by": rg.UpdatedBy, - "updated_time": rg.UpdatedTime, - "vins": rg.VINS, - "vms": rg.Computes, - "resource_types": rg.ResTypes, - "uniq_pools": rg.UniqPools, + "account_acl": flattenRgAcl(rg.ACL), + "account_id": rg.AccountID, + "account_name": rg.AccountName, + "acl": flattenRgAcl(rg.ACL), + "created_by": rg.CreatedBy, + "created_time": rg.CreatedTime, + "def_net_id": rg.DefNetID, + "def_net_type": rg.DefNetType, + "deleted_by": rg.DeletedBy, + "deleted_time": rg.DeletedTime, + "desc": rg.Description, + "dirty": rg.Dirty, + "gid": rg.GID, + "guid": rg.GUID, + "rg_id": rg.ID, + "lock_status": rg.LockStatus, + "milestones": rg.Milestones, + "name": rg.Name, + "register_computes": rg.RegisterComputes, + "resource_limits": flattenRgResourceLimits(rg.ResourceLimits), + "secret": rg.Secret, + "status": rg.Status, + "updated_by": rg.UpdatedBy, + "updated_time": rg.UpdatedTime, + "vins": rg.VINS, + "vms": rg.Computes, + "resource_types": rg.ResTypes, + "uniq_pools": rg.UniqPools, + "cpu_allocation_parameter": rg.CPUAllocationParameter, + "cpu_allocation_ratio": rg.CPUAllocationRatio, } res = append(res, temp) } @@ -265,7 +259,7 @@ func flattenRgList(rgl ListResourceGroups) []map[string]interface{} { } -func flattenRgAcl(rgAcls ListACL) []map[string]interface{} { +func flattenRgAcl(rgAcls rg.ListACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rgAcl := range rgAcls { temp := map[string]interface{}{ @@ -281,7 +275,7 @@ func flattenRgAcl(rgAcls ListACL) []map[string]interface{} { return res } -func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { +func flattenRgResourceLimits(rl rg.ResourceLimits) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cu_c": rl.CUC, @@ -289,7 +283,7 @@ func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { "cu_i": rl.CUI, "cu_m": rl.CUM, "cu_np": rl.CUNP, - "gpu_units": rl.GpuUnits, + "gpu_units": rl.GPUUnits, } res = append(res, temp) @@ -297,7 +291,7 @@ func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { } -func flattenRules(list ListRules) []map[string]interface{} { +func flattenRules(list rg.ListRules) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rule := range list { temp := map[string]interface{}{ @@ -315,7 +309,7 @@ func flattenRules(list ListRules) []map[string]interface{} { return res } -func flattenRgListComputes(lc ListComputes) []map[string]interface{} { +func flattenRgListComputes(lc rg.ListComputes) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, compute := range lc { temp := map[string]interface{}{ @@ -350,7 +344,7 @@ func flattenRgListComputes(lc ListComputes) []map[string]interface{} { return res } -func flattenServerSettings(settings ServerSettings) []map[string]interface{} { +func flattenServerSettings(settings rg.RecordServerSettings) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "inter": settings.Inter, @@ -367,7 +361,7 @@ func flattenServerSettings(settings ServerSettings) []map[string]interface{} { return res } -func flattenListServers(list ListServers) []map[string]interface{} { +func flattenListServers(list rg.ListServers) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, serv := range list { temp := map[string]interface{}{ @@ -384,7 +378,7 @@ func flattenListServers(list ListServers) []map[string]interface{} { return res } -func flattenBackends(b ListBackends) []map[string]interface{} { +func flattenBackends(b rg.ListBackends) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, item := range b { temp := map[string]interface{}{ @@ -399,7 +393,7 @@ func flattenBackends(b ListBackends) []map[string]interface{} { return res } -func flattenBindings(list ListBindings) []map[string]interface{} { +func flattenBindings(list rg.ListBindings) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, bind := range list { temp := map[string]interface{}{ @@ -414,7 +408,7 @@ func flattenBindings(list ListBindings) []map[string]interface{} { return res } -func flattenFrontends(list ListFrontends) []map[string]interface{} { +func flattenFrontends(list rg.ListFrontends) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, front := range list { temp := map[string]interface{}{ @@ -429,7 +423,7 @@ func flattenFrontends(list ListFrontends) []map[string]interface{} { return res } -func flattenNode(node RecordNode) []map[string]interface{} { +func flattenNode(node rg.RecordNode) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "backend_ip": node.BackendIP, @@ -443,7 +437,7 @@ func flattenNode(node RecordNode) []map[string]interface{} { return res } -func flattenRgListLb(listLb ListLB) []map[string]interface{} { +func flattenRgListLb(listLb rg.ListLB) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, lb := range listLb { temp := map[string]interface{}{ @@ -478,7 +472,7 @@ func flattenRgListLb(listLb ListLB) []map[string]interface{} { return res } -func flattenRgListPfw(listPfw ListPFW) []map[string]interface{} { +func flattenRgListPfw(listPfw rg.ListPortForwards) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, pfw := range listPfw { temp := map[string]interface{}{ @@ -497,7 +491,7 @@ func flattenRgListPfw(listPfw ListPFW) []map[string]interface{} { return res } -func flattenRgListVins(lv ListVINS) []map[string]interface{} { +func flattenRgListVins(lv rg.ListVINS) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, vins := range lv { temp := map[string]interface{}{ @@ -525,7 +519,7 @@ func flattenRgListVins(lv ListVINS) []map[string]interface{} { return res } -func flattenRgAffinityGroupComputes(list ListAffinityGroupCompute) []map[string]interface{} { +func flattenRgAffinityGroupComputes(list rg.ListAffinityGroups) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, item := range list { @@ -567,12 +561,12 @@ func flattenRgListGroups(list map[string][]uint64) []map[string]interface{} { return res } -func flattenRgUsageResource(d *schema.ResourceData, usage Resource) { +func flattenRgUsageResource(d *schema.ResourceData, usage rg.RecordResourceUsage) { d.Set("cpu", usage.CPU) d.Set("disk_size", usage.DiskSize) d.Set("disk_size_max", usage.DiskSizeMax) d.Set("extips", usage.ExtIPs) - d.Set("exttraffic", usage.ExtTraffic) + d.Set("exttraffic", usage.ExtraTraffic) d.Set("gpu", usage.GPU) d.Set("ram", usage.RAM) d.Set("seps", flattenRgSeps(usage.SEPs)) diff --git a/internal/service/cloudapi/rg/models.go b/internal/service/cloudapi/rg/models.go index 666267c..a9a8c8d 100644 --- a/internal/service/cloudapi/rg/models.go +++ b/internal/service/cloudapi/rg/models.go @@ -42,12 +42,12 @@ type ResourceLimits struct { } type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get - Cpu int `json:"CU_C"` // CPU count in pcs + Cpu int `json:"CU_C"` // CPU count in pcs Ram float64 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT - Disk int `json:"CU_D"` // Disk capacity in GB - ExtIPs int `json:"CU_I"` // Ext IPs count - ExtTraffic int `json:"CU_NP"` // Ext network traffic - GpuUnits int `json:"gpu_units"` // GPU count + Disk int `json:"CU_D"` // Disk capacity in GB + ExtIPs int `json:"CU_I"` // Ext IPs count + ExtTraffic int `json:"CU_NP"` // Ext network traffic + GpuUnits int `json:"gpu_units"` // GPU count } // Main information about audit diff --git a/internal/service/cloudapi/rg/quota_subresource.go b/internal/service/cloudapi/rg/quota_subresource.go index 2158819..338a114 100644 --- a/internal/service/cloudapi/rg/quota_subresource.go +++ b/internal/service/cloudapi/rg/quota_subresource.go @@ -39,7 +39,7 @@ import ( func makeQuotaRecord(arg_list []interface{}) QuotaRecord { quota := QuotaRecord{ Cpu: -1, - Ram: -1., // this is float64, but may change in the future + Ram: -1, Disk: -1, ExtTraffic: -1, ExtIPs: -1, diff --git a/internal/service/cloudapi/rg/resource_check_input_values.go b/internal/service/cloudapi/rg/resource_check_input_values.go index eb06168..e5a9462 100644 --- a/internal/service/cloudapi/rg/resource_check_input_values.go +++ b/internal/service/cloudapi/rg/resource_check_input_values.go @@ -34,111 +34,54 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) - urlValues := &url.Values{} + req := account.ListRequest{} - accountList := []struct { - ID int `json:"id"` - }{} - - accountListAPI := "/restmachine/cloudapi/account/list" - - accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(accountListRaw), &accountList) + accountList, err := c.CloudAPI().Account().List(ctx, req) if err != nil { return false, err } - haveAccount := false - - myAccount := d.Get("account_id").(int) - for _, account := range accountList { - if account.ID == myAccount { - haveAccount = true - break - } - } - return haveAccount, nil + return len(accountList.FilterByID(accountId)) != 0, nil } func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) - urlValues := &url.Values{} - - locationList := []struct { - GID int `json:"gid"` - }{} - - locationsListAPI := "/restmachine/cloudapi/locations/list" - - locationListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues) - if err != nil { - return false, err - } + req := locations.ListRequest{} - err = json.Unmarshal([]byte(locationListRaw), &locationList) + locationList, err := c.CloudAPI().Locations().List(ctx, req) if err != nil { return false, err } - haveGID := false - - myGID := d.Get("gid").(int) - for _, location := range locationList { - if location.GID == myGID { - haveGID = true - break - } - } - - return haveGID, nil + return len(locationList.FilterByGID(gid)) != 0, nil } func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + extNetId := uint64(d.Get("ext_net_id").(int)) - urlValues := &url.Values{} - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - listExtNet := []struct { - ID int `json:"id"` - }{} - - extNetListAPI := "/restmachine/cloudapi/extnet/list" - - listExtNetRaw, err := c.DecortAPICall(ctx, "POST", extNetListAPI, urlValues) - if err != nil { - return false, err + req := extnet.ListRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(listExtNetRaw), &listExtNet) + listExtNet, err := c.CloudAPI().ExtNet().List(ctx, req) if err != nil { return false, err } - haveExtNet := false - - myExtNetID := d.Get("ext_net_id").(int) - for _, extNet := range listExtNet { - if extNet.ID == myExtNetID { - haveExtNet = true - break - } - } - return haveExtNet, nil + return len(listExtNet.FilterByID(extNetId)) != 0, nil } diff --git a/internal/service/cloudapi/rg/resource_rg.go b/internal/service/cloudapi/rg/resource_rg.go index 4263b58..b10997d 100644 --- a/internal/service/cloudapi/rg/resource_rg.go +++ b/internal/service/cloudapi/rg/resource_rg.go @@ -35,10 +35,10 @@ package rg import ( "context" "fmt" - "net/url" "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" @@ -57,20 +57,6 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter return diag.FromErr(fmt.Errorf("Cannot create new RG: missing name.")) } - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - /* Current version of provider works with default grid id (same is true for disk resources) - grid_id, arg_set := d.GetOk("grid_id") - if !arg_set { - return fmt.Errorf("Cannot create new RG %q in account ID %d: missing Grid ID.", - rg_name.(string), validated_account_id) - } - if grid_id.(int) < 1 { - grid_id = DefaultGridID - } - */ - log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d", rgName.(string), d.Get("account_id").(int)) @@ -99,6 +85,8 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter return diag.Errorf("resourceResgroupCreate: can't create RG because ExtNetID %d is not allowed or does not exist", d.Get("ext_net_id").(int)) } } + c := m.(*controller.ControllerCfg) + req := rg.CreateRequest{} setQuota := false var quotaRecord QuotaRecord @@ -113,67 +101,65 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter c.GetDecortUsername(), rgName.(string), d.Get("account_id").(int)) - urlValues = &url.Values{} - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("name", rgName.(string)) - urlValues.Add("gid", strconv.Itoa(location.DefaultGridID)) - urlValues.Add("owner", c.GetDecortUsername()) + req.AccountID = uint64(d.Get("account_id").(int)) + req.Name = rgName.(string) + req.GID = uint64(location.DefaultGridID) + req.Owner = c.GetDecortUsername() if setQuota { - urlValues.Add("maxCPUCapacity", strconv.Itoa(quotaRecord.Cpu)) - urlValues.Add("maxVDiskCapacity", strconv.Itoa(quotaRecord.Disk)) - urlValues.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotaRecord.Ram)) - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(quotaRecord.ExtTraffic)) - urlValues.Add("maxNumPublicIP", strconv.Itoa(quotaRecord.ExtIPs)) + req.MaxCPUCapacity = int64(quotaRecord.Cpu) + req.MaxVDiskCapacity = int64(quotaRecord.Disk) + req.MaxMemoryCapacity = int64(quotaRecord.Ram) + req.MaxNetworkPeerTransfer = int64(quotaRecord.ExtTraffic) + req.MaxNumPublicIP = int64(quotaRecord.ExtIPs) } defNetType, ok := d.GetOk("def_net_type") if ok { - urlValues.Add("def_net", defNetType.(string)) // NOTE: in API default network type is set by "def_net" parameter + req.DefNet = defNetType.(string) // NOTE: in API default network type is set by "def_net" parameter } else { d.Set("def_net_type", "PRIVATE") } ipcidr, ok := d.GetOk("ipcidr") if ok { - urlValues.Add("ipcidr", ipcidr.(string)) + req.IPCIDR = ipcidr.(string) } description, ok := d.GetOk("description") if ok { - urlValues.Add("desc", description.(string)) + req.Description = description.(string) } reason, ok := d.GetOk("reason") if ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } extNetId, ok := d.GetOk("ext_net_id") if ok { - urlValues.Add("extNetId", strconv.Itoa(extNetId.(int))) + req.ExtNetID = uint64(extNetId.(int)) } extIp, ok := d.GetOk("ext_ip") if ok { - urlValues.Add("extIp", extIp.(string)) + req.ExtIP = extIp.(string) } regComputes, ok := d.GetOk("register_computes") if ok { - urlValues.Add("registerComputes", strconv.FormatBool(regComputes.(bool))) + req.RegisterComputes = regComputes.(bool) } - apiResp, err := c.DecortAPICall(ctx, "POST", ResgroupCreateAPI, urlValues) + apiResp, err := c.CloudAPI().RG().Create(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(apiResp) + d.SetId(strconv.FormatUint(apiResp, 10)) w := dc.Warnings{} if access, ok := d.GetOk("access"); ok { - urlValues = &url.Values{} var user, right string if access.(*schema.Set).Len() > 0 { @@ -183,14 +169,17 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter user = access["user"].(string) right = access["right"].(string) - urlValues.Add("rgId", d.Id()) - urlValues.Add("user", user) - urlValues.Add("right", right) + req := rg.AccessGrantRequest{ + RGID: apiResp, + User: user, + Right: right, + } + if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - _, err := c.DecortAPICall(ctx, "POST", RgAccessGrantAPI, urlValues) + _, err := c.CloudAPI().RG().AccessGrant(ctx, req) if err != nil { w.Add(err) } @@ -200,50 +189,62 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter } if defNet, ok := d.GetOk("def_net"); ok { - urlValues := &url.Values{} - if defNet.(*schema.Set).Len() > 0 { defNetList := defNet.(*schema.Set).List() defNetItem := defNetList[0].(map[string]interface{}) netType := defNetItem["net_type"].(string) - urlValues.Add("rgId", d.Id()) - urlValues.Add("netType", netType) + req := rg.SetDefNetRequest{ + RGID: apiResp, + NetType: netType, + } if netID, ok := defNetItem["net_id"]; ok { - urlValues.Add("netId", strconv.Itoa(netID.(int))) + req.NetID = uint64(netID.(int)) } if reason, ok := defNetItem["reason"]; ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - _, err := c.DecortAPICall(ctx, "POST", RgSetDefNetAPI, urlValues) + _, err := c.CloudAPI().RG().SetDefNet(ctx, req) if err != nil { w.Add(err) } + d.Set("def_net_type", netType) } } if enable, ok := d.GetOk("enable"); ok { - urlValues = &url.Values{} - - api := RgDisableAPI enable := enable.(bool) if enable { - api = RgEnableAPI - } - urlValues.Add("rgId", d.Id()) + req := rg.EnableRequest{ + RGID: apiResp, + } - if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) - } + if reason, ok := d.GetOk("reason"); ok { + req.Reason = reason.(string) + } - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - w.Add(err) + _, err := c.CloudAPI().RG().Enable(ctx, req) + if err != nil { + w.Add(err) + } + } else { + req := rg.DisableRequest{ + RGID: apiResp, + } + + if reason, ok := d.GetOk("reason"); ok { + req.Reason = reason.(string) + } + + _, err := c.CloudAPI().RG().Disable(ctx, req) + if err != nil { + w.Add(err) + } } } @@ -257,7 +258,7 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa c := m.(*controller.ControllerCfg) - rg, err := utilityResgroupCheckPresence(ctx, d, m) + rgData, err := utilityResgroupCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) @@ -265,26 +266,26 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa hasChanged := false - switch rg.Status { + switch rgData.Status { case status.Modeled: - return diag.Errorf("The resource group is in status: %s, please, contact support for more information", rg.Status) + return diag.Errorf("The resource group is in status: %s, please, contact support for more information", rgData.Status) case status.Created: case status.Enabled: case status.Deleted: - urlValues := &url.Values{} - urlValues.Add("rgId", d.Id()) + restoreReq := rg.RestoreRequest{RGID: rgData.ID} + enableReq := rg.EnableRequest{RGID: rgData.ID} - _, err := c.DecortAPICall(ctx, "POST", RgRestoreAPI, urlValues) + _, err := c.CloudAPI().RG().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", RgEnableAPI, urlValues) + + _, err = c.CloudAPI().RG().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } hasChanged = true - case status.Deleting: case status.Destroyed: d.SetId("") @@ -297,13 +298,13 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa } if hasChanged { - rg, err = utilityResgroupCheckPresence(ctx, d, m) + rgData, err = utilityResgroupCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } } - return diag.FromErr(flattenResgroup(d, *rg)) + return diag.FromErr(flattenResgroup(d, *rgData)) } func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -311,7 +312,6 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter d.Get("name").(string), d.Get("account_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} haveAccount, err := existAccountID(ctx, d, m) if err != nil { @@ -326,7 +326,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter return diag.FromErr(err) } if !haveGID { - return diag.Errorf("resourceResgroupUpdate: can't create RG bacause GID %d not allowed or does not exist", d.Get("gid").(int)) + return diag.Errorf("resourceResgroupUpdate: can't create RG because GID %d not allowed or does not exist", d.Get("gid").(int)) } if _, ok := d.GetOk("ext_net_id"); ok { @@ -339,7 +339,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter } } - rgFacts, err := utilityResgroupCheckPresence(ctx, d, m) + rgData, err := utilityResgroupCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) @@ -347,18 +347,20 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter hasChanged := false - switch rgFacts.Status { + switch rgData.Status { case status.Modeled: case status.Created: case status.Enabled: case status.Deleted: - urlValues := &url.Values{} - urlValues.Add("rgId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", RgRestoreAPI, urlValues) + restoreReq := rg.RestoreRequest{RGID: rgData.ID} + enableReq := rg.EnableRequest{RGID: rgData.ID} + + _, err := c.CloudAPI().RG().Restore(ctx, restoreReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", RgEnableAPI, urlValues) + + _, err = c.CloudAPI().RG().Enable(ctx, enableReq) if err != nil { return diag.FromErr(err) } @@ -376,7 +378,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter } if hasChanged { - rgFacts, err = utilityDataResgroupCheckPresence(ctx, d, m) + rgData, err = utilityDataResgroupCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) @@ -411,16 +413,18 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter doGeneralUpdate := false - urlValues = &url.Values{} - urlValues.Add("rgId", d.Id()) + req := rg.UpdateRequest{ + RGID: rgData.ID, + } nameNew, nameSet := d.GetOk("name") if nameSet { log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings.") nameOld, _ := d.GetChange("name") if nameOld.(string) != nameNew.(string) { + req.Name = nameNew.(string) + doGeneralUpdate = true - urlValues.Add("name", nameNew.(string)) } } @@ -435,39 +439,39 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter if quotarecordNew.Cpu != quotarecordOld.Cpu { doGeneralUpdate = true log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecordNew.Cpu, quotarecordOld.Cpu) - urlValues.Add("maxCPUCapacity", strconv.Itoa(quotarecordNew.Cpu)) + req.MaxCPUCapacity = int64(quotarecordNew.Cpu) } if quotarecordNew.Disk != quotarecordOld.Disk { doGeneralUpdate = true log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecordNew.Disk, quotarecordOld.Disk) - urlValues.Add("maxVDiskCapacity", strconv.Itoa(quotarecordNew.Disk)) + req.MaxVDiskCapacity = int64(quotarecordNew.Disk) } if quotarecordNew.Ram != quotarecordOld.Ram { doGeneralUpdate = true log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecordNew.Ram, quotarecordOld.Ram) - urlValues.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecordNew.Ram)) + req.MaxMemoryCapacity = int64(quotarecordNew.Ram) } if quotarecordNew.ExtTraffic != quotarecordOld.ExtTraffic { doGeneralUpdate = true log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecordNew.ExtTraffic, quotarecordOld.ExtTraffic) - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(quotarecordNew.ExtTraffic)) + req.MaxNetworkPeerTransfer = int64(quotarecordNew.ExtTraffic) } if quotarecordNew.ExtIPs != quotarecordOld.ExtIPs { doGeneralUpdate = true log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecordNew.ExtIPs, quotarecordOld.ExtIPs) - urlValues.Add("maxNumPublicIP", strconv.Itoa(quotarecordNew.ExtIPs)) + req.MaxNumPublicIP = int64(quotarecordNew.ExtIPs) } } else { doGeneralUpdate = true - urlValues.Add("maxCPUCapacity", "-1") - urlValues.Add("maxVDiskCapacity", "-1") - urlValues.Add("maxMemoryCapacity", "-1") - urlValues.Add("maxNetworkPeerTransfer", "-1") - urlValues.Add("maxNumPublicIP", "-1") + req.MaxCPUCapacity = -1 + req.MaxVDiskCapacity = -1 + req.MaxMemoryCapacity = -1 + req.MaxNetworkPeerTransfer = -1 + req.MaxNumPublicIP = -1 } descNew, descSet := d.GetOk("description") @@ -476,13 +480,13 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter descOld, _ := d.GetChange("description") if descOld.(string) != descNew.(string) { doGeneralUpdate = true - urlValues.Add("desc", descNew.(string)) + req.Description = descNew.(string) } } if doGeneralUpdate { log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG") - _, err := c.DecortAPICall(ctx, "POST", ResgroupUpdateAPI, urlValues) + _, err := c.CloudAPI().RG().Update(ctx, req) if err != nil { return diag.FromErr(err) } @@ -490,64 +494,63 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter log.Debugf("resourceResgroupUpdate: no difference between old and new state - no update on the RG will be done") } - urlValues = &url.Values{} enableOld, enableNew := d.GetChange("enable") if enableOld.(bool) && !enableNew.(bool) { - urlValues.Add("rgId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", RgDisableAPI, urlValues) + req := rg.DisableRequest{RGID: rgData.ID} + + _, err := c.CloudAPI().RG().Disable(ctx, req) if err != nil { return diag.FromErr(err) } } else if !enableOld.(bool) && enableNew.(bool) { - urlValues.Add("rgId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", RgEnableAPI, urlValues) + req := rg.EnableRequest{RGID: rgData.ID} + + _, err := c.CloudAPI().RG().Enable(ctx, req) if err != nil { return diag.FromErr(err) } } - urlValues = &url.Values{} - oldSet, newSet := d.GetChange("access") deletedAccess := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List() for _, deletedInterface := range deletedAccess { deletedItem := deletedInterface.(map[string]interface{}) - user := deletedItem["user"].(string) - - urlValues.Add("rgId", d.Id()) - urlValues.Add("user", user) + req := rg.AccessRevokeRequest{ + RGID: rgData.ID, + User: user, + } if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - _, err := c.DecortAPICall(ctx, "POST", RgAccessRevokeAPI, urlValues) + _, err := c.CloudAPI().RG().AccessRevoke(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } addedAccess := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List() for _, addedInterface := range addedAccess { addedItem := addedInterface.(map[string]interface{}) - user := addedItem["user"].(string) right := addedItem["right"].(string) - urlValues.Add("rgId", d.Id()) - urlValues.Add("user", user) - urlValues.Add("right", right) + req := rg.AccessGrantRequest{ + RGID: rgData.ID, + User: user, + Right: right, + } + if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - _, err := c.DecortAPICall(ctx, "POST", RgAccessGrantAPI, urlValues) + _, err := c.CloudAPI().RG().AccessGrant(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if ok := d.HasChange("def_net"); ok { @@ -555,22 +558,22 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter if newDefNet.(*schema.Set).Len() > 0 { changedDefNet := (newDefNet.(*schema.Set).Difference(oldDefNet.(*schema.Set))).List() for _, changedDefNetInterface := range changedDefNet { - defNetItem := changedDefNetInterface.(map[string]interface{}) - netType := defNetItem["net_type"].(string) - urlValues.Add("rgId", d.Id()) - urlValues.Add("netType", netType) + req := rg.SetDefNetRequest{ + RGID: rgData.ID, + NetType: netType, + } if netID, ok := defNetItem["net_id"]; ok { - urlValues.Add("netId", strconv.Itoa(netID.(int))) + req.NetID = uint64(netID.(int)) } if reason, ok := defNetItem["reason"]; ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - _, err := c.DecortAPICall(ctx, "POST", RgSetDefNetAPI, urlValues) + _, err := c.CloudAPI().RG().SetDefNet(ctx, req) if err != nil { return diag.FromErr(err) } @@ -582,30 +585,32 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter } func resourceResgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - // NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to - // restore the destroyed resource group as well all Computes & VINSes that existed in it log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d", d.Get("name").(string), d.Get("account_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := rg.DeleteRequest{ + RGID: rgId, + } - urlValues.Add("rgId", d.Id()) if force, ok := d.GetOk("force"); ok { - urlValues.Add("force", strconv.FormatBool(force.(bool))) + req.Force = force.(bool) } if permanently, ok := d.GetOk("permanently"); ok { - urlValues.Add("permanently", strconv.FormatBool(permanently.(bool))) + req.Permanently = permanently.(bool) } if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - _, err := c.DecortAPICall(ctx, "POST", ResgroupDeleteAPI, urlValues) + _, err := c.CloudAPI().RG().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") + return nil } @@ -806,6 +811,10 @@ func ResourceRgSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, + "rg_id": { + Type: schema.TypeInt, + Computed: true, + }, "lock_status": { Type: schema.TypeString, Computed: true, @@ -863,6 +872,14 @@ func ResourceRgSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, }, }, + "cpu_allocation_parameter": { + Type: schema.TypeString, + Computed: true, + }, + "cpu_allocation_ratio": { + Type: schema.TypeFloat, + Computed: true, + }, } } @@ -882,7 +899,7 @@ func ResourceResgroup() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: &constants.Timeout600s, Read: &constants.Timeout300s, - Update: &constants.Timeout300s, + Update: &constants.Timeout600s, Delete: &constants.Timeout300s, Default: &constants.Timeout300s, }, diff --git a/internal/service/cloudapi/rg/utility_rg.go b/internal/service/cloudapi/rg/utility_rg.go index 44c0e70..1b6ed04 100644 --- a/internal/service/cloudapi/rg/utility_rg.go +++ b/internal/service/cloudapi/rg/utility_rg.go @@ -34,79 +34,50 @@ package rg import ( "context" - "encoding/json" - "net/url" "strconv" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -// On success this function returns a string, as returned by API rg/get, which could be unmarshalled -// into ResgroupGetResp structure -func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*RecordResourceGroup, error) { - // This function tries to locate resource group by one of the following algorithms depending - // on the parameters passed: - // - if resource group ID is specified -> by RG ID - // - if resource group name is specifeid -> by RG name and either account ID or account name - // - // If succeeded, it returns non empty string that contains JSON formatted facts about the - // resource group as returned by rg/get API call. - // Otherwise it returns empty string and a meaningful error. - // - // NOTE: As our provider always deletes RGs permanently, there is no "restore" method and - // consequently we are not interested in matching RGs in DELETED state. Hence, we call - // .../rg/list API with includedeleted=false - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for the Terraform resource Exists method. - // - +func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordResourceGroup, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := rg.GetRequest{} if d.Id() != "" { - urlValues.Add("rgId", d.Id()) + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + req.RGID = rgId } else { - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) + req.RGID = uint64(d.Get("rg_id").(int)) } if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - rgData := &RecordResourceGroup{} - rgRaw, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, urlValues) + rgData, err := c.CloudAPI().RG().Get(ctx, req) if err != nil { return nil, err } - err = json.Unmarshal([]byte(rgRaw), rgData) - if err != nil { - return nil, err - } return rgData, nil } -func utilityDataResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*RecordResourceGroup, error) { +func utilityDataResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordResourceGroup, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - rgData := &RecordResourceGroup{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) + req := rg.GetRequest{ + RGID: uint64(d.Get("rg_id").(int)), + } if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req.Reason = reason.(string) } - rgRaw, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, urlValues) + rgData, err := c.CloudAPI().RG().Get(ctx, req) if err != nil { return nil, err } - err = json.Unmarshal([]byte(rgRaw), rgData) - if err != nil { - return nil, err - } return rgData, nil } diff --git a/internal/service/cloudapi/rg/utility_rg_affinity_group_computes.go b/internal/service/cloudapi/rg/utility_rg_affinity_group_computes.go index 13d57f9..481c209 100644 --- a/internal/service/cloudapi/rg/utility_rg_affinity_group_computes.go +++ b/internal/service/cloudapi/rg/utility_rg_affinity_group_computes.go @@ -34,28 +34,20 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityRgAffinityGroupComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListAffinityGroupCompute, error) { +func utilityRgAffinityGroupComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListAffinityGroups, error) { c := m.(*controller.ControllerCfg) - - urlValues := &url.Values{} - listGroupComputes := ListAffinityGroupCompute{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - urlValues.Add("affinityGroup", d.Get("affinity_group").(string)) - - listGroupComputesRaw, err := c.DecortAPICall(ctx, "POST", RgAffinityGroupComputesAPI, urlValues) - if err != nil { - return nil, err + req := rg.AffinityGroupComputesRequest{ + RGID: uint64(d.Get("rg_id").(int)), + AffinityGroup: d.Get("affinity_group").(string), } - err = json.Unmarshal([]byte(listGroupComputesRaw), &listGroupComputes) + + listGroupComputes, err := c.CloudAPI().RG().AffinityGroupComputes(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_affinity_groups_get.go b/internal/service/cloudapi/rg/utility_rg_affinity_groups_get.go index f209ad4..e2106c5 100644 --- a/internal/service/cloudapi/rg/utility_rg_affinity_groups_get.go +++ b/internal/service/cloudapi/rg/utility_rg_affinity_groups_get.go @@ -34,29 +34,20 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func utilityRgAffinityGroupsGetCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]uint64, error) { c := m.(*controller.ControllerCfg) - - urlValues := &url.Values{} - computes := make([]uint64, 0) - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - urlValues.Add("affinityGroup", d.Get("affinity_group").(string)) - - computesRaw, err := c.DecortAPICall(ctx, "POST", RgAffinityGroupsGetAPI, urlValues) - if err != nil { - return nil, err + req := rg.AffinityGroupsGetRequest{ + RGID: uint64(d.Get("rg_id").(int)), + AffinityGroup: d.Get("affinity_group").(string), } - err = json.Unmarshal([]byte(computesRaw), &computes) + computes, err := c.CloudAPI().RG().AffinityGroupsGet(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_affinity_groups_list.go b/internal/service/cloudapi/rg/utility_rg_affinity_groups_list.go index 81347f5..2f61129 100644 --- a/internal/service/cloudapi/rg/utility_rg_affinity_groups_list.go +++ b/internal/service/cloudapi/rg/utility_rg_affinity_groups_list.go @@ -34,28 +34,19 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func utilityRgAffinityGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (map[string][]uint64, error) { c := m.(*controller.ControllerCfg) - - urlValues := &url.Values{} - groups := make(map[string][]uint64, 0) - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - - groupsRaw, err := c.DecortAPICall(ctx, "POST", RgAffinityGroupsListAPI, urlValues) - if err != nil { - return nil, err + req := rg.AffinityGroupsListRequest{ + RGID: uint64(d.Get("rg_id").(int)), } - err = json.Unmarshal([]byte(groupsRaw), &groups) + groups, err := c.CloudAPI().RG().AffinityGroupsList(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_audits.go b/internal/service/cloudapi/rg/utility_rg_audits.go index b507dbc..cf96580 100644 --- a/internal/service/cloudapi/rg/utility_rg_audits.go +++ b/internal/service/cloudapi/rg/utility_rg_audits.go @@ -34,26 +34,19 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityRgAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListAudits, error) { +func utilityRgAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListAudits, error) { c := m.(*controller.ControllerCfg) - - urlValues := &url.Values{} - rgAudits := ListAudits{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - rgAuditsRow, err := c.DecortAPICall(ctx, "POST", RgAuditsAPI, urlValues) - if err != nil { - return nil, err + req := rg.AuditsRequest{ + RGID: uint64(d.Get("rg_id").(int)), } - err = json.Unmarshal([]byte(rgAuditsRow), &rgAudits) + + rgAudits, err := c.CloudAPI().RG().Audits(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_list.go b/internal/service/cloudapi/rg/utility_rg_list.go index e096132..50aae56 100644 --- a/internal/service/cloudapi/rg/utility_rg_list.go +++ b/internal/service/cloudapi/rg/utility_rg_list.go @@ -34,39 +34,30 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListResourceGroups, error) { +func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListResourceGroups, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - rgList := ListResourceGroups{} + req := rg.ListRequest{} if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if includedeleted, ok := d.GetOk("includedeleted"); ok { - urlValues.Add("includedeleted", strconv.FormatBool(includedeleted.(bool))) + req.IncludeDeleted = includedeleted.(bool) } log.Debugf("utilityRgListCheckPresence: load rg list") - rgListRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(rgListRaw), &rgList) + rgList, err := c.CloudAPI().RG().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_list_computes.go b/internal/service/cloudapi/rg/utility_rg_list_computes.go index 5bb931a..4c30ab1 100644 --- a/internal/service/cloudapi/rg/utility_rg_list_computes.go +++ b/internal/service/cloudapi/rg/utility_rg_list_computes.go @@ -34,31 +34,23 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityRgListComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListComputes, error) { +func utilityRgListComputesCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListComputes, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - listComputes := ListComputes{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req := rg.ListComputesRequest{ + RGID: uint64(d.Get("rg_id").(int)), } - listComputesRaw, err := c.DecortAPICall(ctx, "POST", RgListComputesAPI, urlValues) - if err != nil { - return nil, err + if reason, ok := d.GetOk("reason"); ok { + req.Reason = reason.(string) } - err = json.Unmarshal([]byte(listComputesRaw), &listComputes) + listComputes, err := c.CloudAPI().RG().ListComputes(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_list_deleted.go b/internal/service/cloudapi/rg/utility_rg_list_deleted.go index 1163524..402ae21 100644 --- a/internal/service/cloudapi/rg/utility_rg_list_deleted.go +++ b/internal/service/cloudapi/rg/utility_rg_list_deleted.go @@ -34,33 +34,24 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityRgListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListResourceGroups, error) { +func utilityRgListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListResourceGroups, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - rgList := ListResourceGroups{} + req := rg.ListDeletedRequest{} if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) - } - - rgListRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListDeletedAPI, urlValues) - if err != nil { - return nil, err + req.Page = uint64(page.(int)) } - err = json.Unmarshal([]byte(rgListRaw), &rgList) + rgList, err := c.CloudAPI().RG().ListDeleted(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_list_lb.go b/internal/service/cloudapi/rg/utility_rg_list_lb.go index 86a2467..69f7093 100644 --- a/internal/service/cloudapi/rg/utility_rg_list_lb.go +++ b/internal/service/cloudapi/rg/utility_rg_list_lb.go @@ -34,28 +34,19 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityRgListLbCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListLB, error) { +func utilityRgListLbCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListLB, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - listLb := ListLB{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - - listLbRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListLbAPI, urlValues) - if err != nil { - return nil, err + req := rg.ListLBRequest{ + RGID: uint64(d.Get("rg_id").(int)), } - err = json.Unmarshal([]byte(listLbRaw), &listLb) + listLb, err := c.CloudAPI().RG().ListLB(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_list_pfw.go b/internal/service/cloudapi/rg/utility_rg_list_pfw.go index a0d54f1..e0eeff7 100644 --- a/internal/service/cloudapi/rg/utility_rg_list_pfw.go +++ b/internal/service/cloudapi/rg/utility_rg_list_pfw.go @@ -34,28 +34,19 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityRgListPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListPFW, error) { +func utilityRgListPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListPortForwards, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - listPfw := ListPFW{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - - listPfwRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListPfwAPI, urlValues) - if err != nil { - return nil, err + req := rg.ListPFWRequest{ + RGID: uint64(d.Get("rg_id").(int)), } - err = json.Unmarshal([]byte(listPfwRaw), &listPfw) + listPfw, err := c.CloudAPI().RG().ListPFW(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_list_vins.go b/internal/service/cloudapi/rg/utility_rg_list_vins.go index 5211e95..f77c195 100644 --- a/internal/service/cloudapi/rg/utility_rg_list_vins.go +++ b/internal/service/cloudapi/rg/utility_rg_list_vins.go @@ -34,32 +34,23 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityRgListVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ListVINS, error) { +func utilityRgListVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - listVins := ListVINS{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - - if val, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", val.(string)) + req := rg.ListVINSRequest{ + RGID: uint64(d.Get("rg_id").(int)), } - listVinsRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListVinsAPI, urlValues) - if err != nil { - return nil, err + if val, ok := d.GetOk("reason"); ok { + req.Reason = val.(string) } - err = json.Unmarshal([]byte(listVinsRaw), &listVins) + listVins, err := c.CloudAPI().RG().ListVINS(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/rg/utility_rg_usage.go b/internal/service/cloudapi/rg/utility_rg_usage.go index 329ed0d..e51d24e 100644 --- a/internal/service/cloudapi/rg/utility_rg_usage.go +++ b/internal/service/cloudapi/rg/utility_rg_usage.go @@ -34,34 +34,26 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityDataRgUsageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Resource, error) { +func utilityDataRgUsageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordResourceUsage, error) { c := m.(*controller.ControllerCfg) - urlValues := url.Values{} - usage := Resource{} - - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - - if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) + req := rg.UsageRequest{ + RGID: uint64(d.Get("rg_id").(int)), } - usageRaw, err := c.DecortAPICall(ctx, "POST", ResgroupUsageAPI, &urlValues) - if err != nil { - return nil, err + if reason, ok := d.GetOk("reason"); ok { + req.Reason = reason.(string) } - err = json.Unmarshal([]byte(usageRaw), &usage) + usage, err := c.CloudAPI().RG().Usage(ctx, req) if err != nil { return nil, err } - return &usage, nil + return usage, nil } diff --git a/internal/service/cloudapi/snapshot/api.go b/internal/service/cloudapi/snapshot/api.go deleted file mode 100644 index e5ab471..0000000 --- a/internal/service/cloudapi/snapshot/api.go +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package snapshot - -const snapshotCreateAPI = "/restmachine/cloudapi/compute/snapshotCreate" -const snapshotDeleteAPI = "/restmachine/cloudapi/compute/snapshotDelete" -const snapshotRollbackAPI = "/restmachine/cloudapi/compute/snapshotRollback" -const snapshotListAPI = "/restmachine/cloudapi/compute/snapshotList" diff --git a/internal/service/cloudapi/snapshot/data_source_snapshot_list.go b/internal/service/cloudapi/snapshot/data_source_snapshot_list.go index dce27c2..4ea1dde 100644 --- a/internal/service/cloudapi/snapshot/data_source_snapshot_list.go +++ b/internal/service/cloudapi/snapshot/data_source_snapshot_list.go @@ -41,21 +41,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenSnapshotList(gl SnapshotList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, item := range gl { - temp := map[string]interface{}{ - "label": item.Label, - "guid": item.Guid, - "disks": item.Disks, - "timestamp": item.Timestamp, - } - - res = append(res, temp) - } - return res -} - func dataSourceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { snapshotList, err := utilitySnapshotListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudapi/snapshot/flattens.go b/internal/service/cloudapi/snapshot/flattens.go new file mode 100644 index 0000000..85709f3 --- /dev/null +++ b/internal/service/cloudapi/snapshot/flattens.go @@ -0,0 +1,28 @@ +package snapshot + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" +) + +func flattenSnapshotList(gl compute.ListSnapShots) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range gl { + temp := map[string]interface{}{ + "label": item.Label, + "guid": item.GUID, + "disks": item.Disks, + "timestamp": item.Timestamp, + } + + res = append(res, temp) + } + return res +} + +func flattenSnapshot(d *schema.ResourceData, snapshot *compute.ItemSnapshot) { + d.Set("timestamp", snapshot.Timestamp) + d.Set("guid", snapshot.GUID) + d.Set("disks", snapshot.Disks) + d.Set("label", snapshot.Label) +} diff --git a/internal/service/cloudapi/snapshot/models.go b/internal/service/cloudapi/snapshot/models.go deleted file mode 100644 index 9a08e4b..0000000 --- a/internal/service/cloudapi/snapshot/models.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package snapshot - -type Snapshot struct { - Disks []int `json:"disks"` - Guid string `json:"guid"` - Label string `json:"label"` - Timestamp uint64 `json:"timestamp"` -} - -type SnapshotList []Snapshot diff --git a/internal/service/cloudapi/snapshot/resource_snapshot.go b/internal/service/cloudapi/snapshot/resource_snapshot.go index 7a1084a..6f236f8 100644 --- a/internal/service/cloudapi/snapshot/resource_snapshot.go +++ b/internal/service/cloudapi/snapshot/resource_snapshot.go @@ -34,13 +34,12 @@ package snapshot import ( "context" - "net/url" - "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -49,11 +48,12 @@ func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m inter log.Debugf("resourceSnapshotCreate: called for snapshot %s", d.Get("label").(string)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("label", d.Get("label").(string)) - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) + req := compute.SnapshotCreateRequest{ + Label: d.Get("label").(string), + ComputeID: uint64(d.Get("compute_id").(int)), + } - snapshotId, err := c.DecortAPICall(ctx, "POST", snapshotCreateAPI, urlValues) + snapshotId, err := c.CloudAPI().Compute().SnapshotCreate(ctx, req) if err != nil { return diag.FromErr(err) } @@ -63,12 +63,7 @@ func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m inter d.SetId(snapshotId) d.Set("guid", snapshotId) - diagnostics := resourceSnapshotRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceSnapshotRead(ctx, d, m) } func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -77,10 +72,7 @@ func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interfa return diag.FromErr(err) } - d.Set("timestamp", snapshot.Timestamp) - d.Set("guid", snapshot.Guid) - d.Set("disks", snapshot.Disks) - d.Set("label", snapshot.Label) + flattenSnapshot(d, snapshot) return nil } @@ -89,20 +81,22 @@ func resourceSnapshotDelete(ctx context.Context, d *schema.ResourceData, m inter log.Debugf("resourceSnapshotDelete: called for %s, id: %s", d.Get("label").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("label", d.Get("label").(string)) + req := compute.SnapshotDeleteRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Label: d.Get("label").(string), + } - _, err := c.DecortAPICall(ctx, "POST", snapshotDeleteAPI, urlValues) + _, err := c.CloudAPI().Compute().SnapshotDelete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } -func resourceSnapshotEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { if d.HasChange("rollback") { if d.Get("rollback").(bool) { err := resourceSnapshotRollback(ctx, d, m) @@ -117,12 +111,12 @@ func resourceSnapshotEdit(ctx context.Context, d *schema.ResourceData, m interfa func resourceSnapshotRollback(ctx context.Context, d *schema.ResourceData, m interface{}) error { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("label", d.Get("label").(string)) + req := compute.SnapshotRollbackRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Label: d.Get("label").(string), + } - _, err := c.DecortAPICall(ctx, "POST", snapshotRollbackAPI, urlValues) + _, err := c.CloudAPI().Compute().SnapshotRollback(ctx, req) if err != nil { return err } @@ -175,7 +169,7 @@ func ResourceSnapshot() *schema.Resource { CreateContext: resourceSnapshotCreate, ReadContext: resourceSnapshotRead, - UpdateContext: resourceSnapshotEdit, + UpdateContext: resourceSnapshotUpdate, DeleteContext: resourceSnapshotDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudapi/snapshot/utility_snapshot.go b/internal/service/cloudapi/snapshot/utility_snapshot.go index 8749e52..8c099a6 100644 --- a/internal/service/cloudapi/snapshot/utility_snapshot.go +++ b/internal/service/cloudapi/snapshot/utility_snapshot.go @@ -37,9 +37,10 @@ import ( "errors" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" ) -func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Snapshot, error) { +func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemSnapshot, error) { snapShotList, err := utilitySnapshotListCheckPresence(ctx, d, m) if err != nil { return nil, err @@ -54,7 +55,7 @@ func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m } for _, s := range snapShotList { - if s.Guid == findId { + if s.GUID == findId { return &s, nil } } diff --git a/internal/service/cloudapi/snapshot/utility_snapshot_list.go b/internal/service/cloudapi/snapshot/utility_snapshot_list.go index 85f21ee..1a7ae80 100644 --- a/internal/service/cloudapi/snapshot/utility_snapshot_list.go +++ b/internal/service/cloudapi/snapshot/utility_snapshot_list.go @@ -34,31 +34,20 @@ package snapshot import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilitySnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SnapshotList, error) { +func utilitySnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListSnapShots, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - - resp, err := c.DecortAPICall(ctx, "POST", snapshotListAPI, urlValues) - if err != nil { - return nil, err + req := compute.SnapshotListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), } - if resp == "" { - return nil, nil - } - - snapshotList := SnapshotList{} - if err := json.Unmarshal([]byte(resp), &snapshotList); err != nil { - + snapshotList, err := c.CloudAPI().Compute().SnapshotList(ctx, req) + if err != nil { return nil, err } diff --git a/internal/service/cloudapi/vins/api.go b/internal/service/cloudapi/vins/api.go deleted file mode 100644 index c6d61ca..0000000 --- a/internal/service/cloudapi/vins/api.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package vins - -const ( - VinsAuditsAPI = "/restmachine/cloudapi/vins/audits" - VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount" - VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG" - VinsDeleteAPI = "/restmachine/cloudapi/vins/delete" - VinsDisableAPI = "/restmachine/cloudapi/vins/disable" - VinsEnableAPI = "/restmachine/cloudapi/vins/enable" - VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect" - VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect" - VinsExtNetListAPI = "/restmachine/cloudapi/vins/extNetList" - VinsGetAPI = "/restmachine/cloudapi/vins/get" - VinsIpListAPI = "/restmachine/cloudapi/vins/ipList" - VinsIpReleaseAPI = "/restmachine/cloudapi/vins/ipRelease" - VinsIpReserveAPI = "/restmachine/cloudapi/vins/ipReserve" - VinsListAPI = "/restmachine/cloudapi/vins/list" - VinsListDeletedAPI = "/restmachine/cloudapi/vins/listDeleted" - VinsNatRuleAddAPI = "/restmachine/cloudapi/vins/natRuleAdd" - VinsNatRuleDelAPI = "/restmachine/cloudapi/vins/natRuleDel" - VinsNatRuleListAPI = "/restmachine/cloudapi/vins/natRuleList" - VinsRestoreAPI = "/restmachine/cloudapi/vins/restore" - VinsSearchAPI = "/restmachine/cloudapi/vins/search" - VinsVnfdevRedeployAPI = "/restmachine/cloudapi/vins/vnfdevRedeploy" - VinsVnfdevRestartAPI = "/restmachine/cloudapi/vins/vnfdevRestart" -) diff --git a/internal/service/cloudapi/vins/data_source_vins_ip_list.go b/internal/service/cloudapi/vins/data_source_vins_ip_list.go index 76c7d2d..5003189 100644 --- a/internal/service/cloudapi/vins/data_source_vins_ip_list.go +++ b/internal/service/cloudapi/vins/data_source_vins_ip_list.go @@ -57,7 +57,7 @@ func DataSourceVinsIpListSchemaMake() map[string]*schema.Schema { "vins_id": { Type: schema.TypeInt, Required: true, - Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + Description: "Unique ID of the ViNS", }, "items": { Type: schema.TypeList, diff --git a/internal/service/cloudapi/vins/flattens.go b/internal/service/cloudapi/vins/flattens.go index 031fc23..ce2b16c 100644 --- a/internal/service/cloudapi/vins/flattens.go +++ b/internal/service/cloudapi/vins/flattens.go @@ -32,12 +32,15 @@ Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/w package vins -import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" +) -func flattenMGMT(mgmt *VNFConfigMGMT) []map[string]interface{} { +func flattenMGMT(mgmt vins.RecordMGMT) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ - "ip_addr": mgmt.IPAddr, + "ip_addr": mgmt.IPAddress, "password": mgmt.Password, "ssh_key": mgmt.SSHKey, "user": mgmt.User, @@ -46,7 +49,7 @@ func flattenMGMT(mgmt *VNFConfigMGMT) []map[string]interface{} { return res } -func flattenResources(resources *VNFConfigResources) []map[string]interface{} { +func flattenResources(resources *vins.RecordResources) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cpu": resources.CPU, @@ -58,17 +61,17 @@ func flattenResources(resources *VNFConfigResources) []map[string]interface{} { return res } -func flattenConfig(config VNFConfig) []map[string]interface{} { +func flattenConfig(config vins.RecordVNFConfig) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ - "mgmt": flattenMGMT(&config.MGMT), + "mgmt": flattenMGMT(config.MGMT), "resources": flattenResources(&config.Resources), } res = append(res, temp) return res } -func flattenQOS(qos QOS) []map[string]interface{} { +func flattenQOS(qos vins.QOS) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "e_rate": qos.ERate, @@ -80,7 +83,7 @@ func flattenQOS(qos QOS) []map[string]interface{} { return res } -func flattenInterfaces(interfaces VNFInterfaceList) []map[string]interface{} { +func flattenInterfaces(interfaces []vins.ItemVNFInterface) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, vnfInterface := range interfaces { @@ -88,7 +91,7 @@ func flattenInterfaces(interfaces VNFInterfaceList) []map[string]interface{} { "conn_id": vnfInterface.ConnID, "conn_type": vnfInterface.ConnType, "def_gw": vnfInterface.DefGW, - "flipgroup_id": vnfInterface.FlipGroupID, + "flipgroup_id": vnfInterface.FLIPGroupID, "guid": vnfInterface.GUID, "ip_address": vnfInterface.IPAddress, "listen_ssh": vnfInterface.ListenSSH, @@ -101,7 +104,7 @@ func flattenInterfaces(interfaces VNFInterfaceList) []map[string]interface{} { "qos": flattenQOS(vnfInterface.QOS), "target": vnfInterface.Target, "type": vnfInterface.Type, - "vnfs": vnfInterface.VNFS, + "vnfs": vnfInterface.VNFs, } res = append(res, temp) } @@ -109,7 +112,7 @@ func flattenInterfaces(interfaces VNFInterfaceList) []map[string]interface{} { return res } -func flattenVNFDev(vnfDev VNFDev) []map[string]interface{} { +func flattenVNFDev(vnfDev vins.RecordVNFDev) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "_ckey": vnfDev.CKey, @@ -137,7 +140,7 @@ func flattenVNFDev(vnfDev VNFDev) []map[string]interface{} { return res } -func flattenComputes(computes VINSComputeList) []map[string]interface{} { +func flattenComputes(computes vins.ListVINSComputes) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, compute := range computes { temp := map[string]interface{}{ @@ -150,14 +153,14 @@ func flattenComputes(computes VINSComputeList) []map[string]interface{} { return res } -func flattenReservations(reservations ReservationList) []map[string]interface{} { +func flattenReservations(reservations vins.ListReservations) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, reservation := range reservations { temp := map[string]interface{}{ "client_type": reservation.ClientType, "desc": reservation.Description, "domainname": reservation.DomainName, - "hostname": reservation.HostName, + "hostname": reservation.Hostname, "ip": reservation.IP, "mac": reservation.MAC, "type": reservation.Type, @@ -169,7 +172,7 @@ func flattenReservations(reservations ReservationList) []map[string]interface{} return res } -func flattenDHCPConfig(config DHCPConfig) []map[string]interface{} { +func flattenDHCPConfig(config vins.RecordDHCPConfig) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "default_gw": config.DefaultGW, @@ -177,7 +180,7 @@ func flattenDHCPConfig(config DHCPConfig) []map[string]interface{} { "ip_end": config.IPEnd, "ip_start": config.IPStart, "lease": config.Lease, - "netmask": config.Netmask, + "netmask": config.NetMask, "network": config.Network, "reservations": flattenReservations(config.Reservations), } @@ -186,7 +189,7 @@ func flattenDHCPConfig(config DHCPConfig) []map[string]interface{} { return res } -func flattenPrimary(primary DevicePrimary) []map[string]interface{} { +func flattenPrimary(primary vins.RecordPrimary) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "dev_id": primary.DevID, @@ -198,7 +201,7 @@ func flattenPrimary(primary DevicePrimary) []map[string]interface{} { return res } -func flattenDevices(devices Devices) []map[string]interface{} { +func flattenDevices(devices vins.RecordDevices) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "primary": flattenPrimary(devices.Primary), @@ -208,7 +211,7 @@ func flattenDevices(devices Devices) []map[string]interface{} { return res } -func flattenDHCP(dhcp DHCP) []map[string]interface{} { +func flattenDHCP(dhcp vins.RecordDHCP) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "_ckey": dhcp.CKey, @@ -233,7 +236,7 @@ func flattenDHCP(dhcp DHCP) []map[string]interface{} { return res } -func flattenGWConfig(config GWConfig) []map[string]interface{} { +func flattenGWConfig(config vins.RecordGWConfig) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "default_gw": config.DefaultGW, @@ -247,7 +250,7 @@ func flattenGWConfig(config GWConfig) []map[string]interface{} { return res } -func flattenGW(gw GW) []map[string]interface{} { +func flattenGW(gw vins.RecordGW) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "_ckey": gw.CKey, @@ -272,7 +275,7 @@ func flattenGW(gw GW) []map[string]interface{} { return res } -func flattenRules(rules ListNATRules) []map[string]interface{} { +func flattenRules(rules vins.ListNATRules) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rule := range rules { tmp := map[string]interface{}{ @@ -290,7 +293,7 @@ func flattenRules(rules ListNATRules) []map[string]interface{} { return res } -func flattenNATConfig(config NATConfig) []map[string]interface{} { +func flattenNATConfig(config vins.NATConfig) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "net_mask": config.NetMask, @@ -303,7 +306,7 @@ func flattenNATConfig(config NATConfig) []map[string]interface{} { } -func flattenNAT(nat NAT) []map[string]interface{} { +func flattenNAT(nat vins.RecordNAT) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "_ckey": nat.CKey, @@ -328,7 +331,7 @@ func flattenNAT(nat NAT) []map[string]interface{} { return res } -func flattenVNFS(vnfs VNFS) []map[string]interface{} { +func flattenVNFS(vnfs vins.RecordVNFs) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "dhcp": flattenDHCP(vnfs.DHCP), @@ -340,7 +343,7 @@ func flattenVNFS(vnfs VNFS) []map[string]interface{} { return res } -func flattenRuleBlock(rules ListNATRules) []map[string]interface{} { +func flattenRuleBlock(rules vins.ListNATRules) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rule := range rules { tmp := map[string]interface{}{ @@ -356,7 +359,7 @@ func flattenRuleBlock(rules ListNATRules) []map[string]interface{} { return res } -func flattenVins(d *schema.ResourceData, vins VINSDetailed) { +func flattenVins(d *schema.ResourceData, vins vins.RecordVINS) { d.Set("vins_id", vins.ID) d.Set("vnf_dev", flattenVNFDev(vins.VNFDev)) d.Set("_ckey", vins.CKey) @@ -382,12 +385,12 @@ func flattenVins(d *schema.ResourceData, vins VINSDetailed) { d.Set("sec_vnf_dev_id", vins.SecVNFDevID) d.Set("status", vins.Status) d.Set("user_managed", vins.UserManaged) - d.Set("vnfs", flattenVNFS(vins.VNFS)) - d.Set("vxlan_id", vins.VXLanID) - d.Set("nat_rule", flattenRuleBlock(vins.VNFS.NAT.Config.Rules)) + d.Set("vnfs", flattenVNFS(vins.VNFs)) + d.Set("vxlan_id", vins.VXLANID) + d.Set("nat_rule", flattenRuleBlock(vins.VNFs.NAT.Config.Rules)) } -func flattenVinsData(d *schema.ResourceData, vins VINSDetailed) { +func flattenVinsData(d *schema.ResourceData, vins vins.RecordVINS) { d.Set("vins_id", vins.ID) d.Set("vnf_dev", flattenVNFDev(vins.VNFDev)) d.Set("_ckey", vins.CKey) @@ -413,11 +416,11 @@ func flattenVinsData(d *schema.ResourceData, vins VINSDetailed) { d.Set("sec_vnf_dev_id", vins.SecVNFDevID) d.Set("status", vins.Status) d.Set("user_managed", vins.UserManaged) - d.Set("vnfs", flattenVNFS(vins.VNFS)) - d.Set("vxlan_id", vins.VXLanID) + d.Set("vnfs", flattenVNFS(vins.VNFs)) + d.Set("vxlan_id", vins.VXLANID) } -func flattenVinsAudits(auidts VINSAuditsList) []map[string]interface{} { +func flattenVinsAudits(auidts vins.ListAudits) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, audit := range auidts { temp := map[string]interface{}{ @@ -433,7 +436,7 @@ func flattenVinsAudits(auidts VINSAuditsList) []map[string]interface{} { return res } -func flattenVinsExtNetList(extNetList ExtNetList) []map[string]interface{} { +func flattenVinsExtNetList(extNetList vins.ListExtNets) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, extNet := range extNetList { temp := map[string]interface{}{ @@ -450,13 +453,13 @@ func flattenVinsExtNetList(extNetList ExtNetList) []map[string]interface{} { return res } -func flattenVinsIpList(ips IPList) []map[string]interface{} { +func flattenVinsIpList(ips vins.ListIPs) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, ip := range ips { temp := map[string]interface{}{ "client_type": ip.ClientType, "domainname": ip.DomainName, - "hostname": ip.HostName, + "hostname": ip.Hostname, "ip": ip.IP, "mac": ip.MAC, "type": ip.Type, @@ -468,7 +471,7 @@ func flattenVinsIpList(ips IPList) []map[string]interface{} { return res } -func flattenVinsList(vl VINSList) []map[string]interface{} { +func flattenVinsList(vl vins.ListVINS) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, v := range vl { temp := map[string]interface{}{ @@ -494,7 +497,7 @@ func flattenVinsList(vl VINSList) []map[string]interface{} { return res } -func flattenVinsNatRuleList(natRules NATRuleList) []map[string]interface{} { +func flattenVinsNatRuleList(natRules vins.ListNATRules) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, natRule := range natRules { temp := map[string]interface{}{ diff --git a/internal/service/cloudapi/vins/models.go b/internal/service/cloudapi/vins/models.go deleted file mode 100644 index 061b2f8..0000000 --- a/internal/service/cloudapi/vins/models.go +++ /dev/null @@ -1,330 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, -Kasim Baybikov, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package vins - -type VINSRecord struct { - AccountID uint64 `json:"accountId"` - AccountName string `json:"accountName"` - CreatedBy string `json:"createdBy"` - CreatedTime uint64 `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime uint64 `json:"deletedTime"` - ExternalIP string `json:"externalIP"` - ID uint64 `json:"id"` - Name string `json:"name"` - Network string `json:"network"` - RGID uint64 `json:"rgId"` - RGName string `json:"rgName"` - Status string `json:"status"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime uint64 `json:"updatedTime"` - VXLANID uint64 `json:"vxlanId"` -} - -type VINSList []VINSRecord - -type VINSAudits struct { - Call string `json:"call"` - ResponseTime float64 `json:"responsetime"` - StatusCode uint64 `json:"statuscode"` - Timestamp float64 `json:"timestamp"` - User string `json:"user"` -} - -type VINSAuditsList []VINSAudits - -type VINSExtNet struct { - DefaultGW string `json:"default_gw"` - ExtNetID uint64 `json:"ext_net_id"` - IP string `json:"ip"` - PrefixLen uint64 `json:"prefixlen"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` -} - -type ExtNetList []VINSExtNet - -type IP struct { - ClientType string `json:"clientType"` - DomainName string `json:"domainname"` - HostName string `json:"hostname"` - IP string `json:"ip"` - MAC string `json:"mac"` - Type string `json:"type"` - VMID uint64 `json:"vmId"` -} - -type IPList []IP - -type VNFDev struct { - CKey string `json:"_ckey"` - AccountID uint64 `json:"accountId"` - Capabilities []string `json:"capabilities"` - Config VNFConfig `json:"config"` - ConfigSaved bool `json:"configSaved"` - CustomPreConfig bool `json:"customPrecfg"` - Description string `json:"desc"` - GID uint64 `json:"gid"` - GUID uint64 `json:"guid"` - ID uint64 `json:"id"` - Interfaces VNFInterfaceList `json:"interfaces"` - LockStatus string `json:"lockStatus"` - Milestones uint64 `json:"milestones"` - Name string `json:"name"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` - VINS []uint64 `json:"vins"` -} - -type VNFConfig struct { - MGMT VNFConfigMGMT `json:"mgmt"` - Resources VNFConfigResources `json:"resources"` -} - -type VNFConfigMGMT struct { - IPAddr string `json:"ipaddr"` - Password string `json:"password"` - SSHKey string `json:"sshkey"` - User string `json:"user"` -} - -type VNFConfigResources struct { - CPU uint64 `json:"cpu"` - RAM uint64 `json:"ram"` - StackID uint64 `json:"stackId"` - UUID string `json:"uuid"` -} - -type VNFInterface struct { - ConnID uint64 `json:"connId"` - ConnType string `json:"connType"` - DefGW string `json:"defGw"` - FlipGroupID uint64 `json:"flipgroupId"` - GUID string `json:"guid"` - IPAddress string `json:"ipAddress"` - ListenSSH bool `json:"listenSsh"` - MAC string `json:"mac"` - Name string `json:"name"` - NetID uint64 `json:"netId"` - NetMask uint64 `json:"netMask"` - NetType string `json:"netType"` - PCISlot uint64 `json:"pciSlot"` - QOS QOS `json:"qos"` - Target string `json:"target"` - Type string `json:"type"` - VNFS []uint64 `json:"vnfs"` -} - -type QOS struct { - ERate uint64 `json:"eRate"` - GUID string `json:"guid"` - InBurst uint64 `json:"inBurst"` - InRate uint64 `json:"inRate"` -} - -type VNFInterfaceList []VNFInterface - -type VINSCompute struct { - ID uint64 `json:"id"` - Name string `json:"name"` -} - -type VINSComputeList []VINSCompute - -type VNFS struct { - DHCP DHCP `json:"DHCP"` - GW GW `json:"GW"` - NAT NAT `json:"NAT"` -} - -type NAT struct { - CKey string `json:"_ckey"` - AccountID uint64 `json:"accountId"` - CreatedTime uint64 `json:"createdTime"` - Config NATConfig `json:"config"` - Devices Devices `json:"devices"` - GID uint64 `json:"gid"` - GUID uint64 `json:"guid"` - ID uint64 `json:"id"` - LockStatus string `json:"lockStatus"` - Milestones uint64 `json:"milestones"` - OwnerID uint64 `json:"ownerId"` - OwnerType string `json:"ownerType"` - PureVirtual bool `json:"pureVirtual"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` -} - -type NATConfig struct { - NetMask uint64 `json:"netmask"` - Network string `json:"network"` - Rules ListNATRules `json:"rules"` -} - -type ItemNATRule struct { - ID uint64 `json:"id"` - LocalIP string `json:"localIp"` - LocalPort uint64 `json:"localPort"` - Protocol string `json:"protocol"` - PublicPortEnd uint64 `json:"publicPortEnd"` - PublicPortStart uint64 `json:"publicPortStart"` - VMID uint64 `json:"vmId"` - VMName string `json:"vmName"` -} - -type ListNATRules []ItemNATRule - -type GW struct { - CKey string `json:"_ckey"` - AccountID uint64 `json:"accountId"` - Config GWConfig `json:"config"` - CreatedTime uint64 `json:"createdTime"` - Devices Devices `json:"devices"` - GID uint64 `json:"gid"` - GUID uint64 `json:"guid"` - ID uint64 `json:"id"` - LockStatus string `json:"lockStatus"` - Milestones uint64 `json:"milestones"` - OwnerID uint64 `json:"ownerId"` - OwnerType string `json:"ownerType"` - PureVirtual bool `json:"pureVirtual"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` -} - -type GWConfig struct { - DefaultGW string `json:"default_gw"` - ExtNetID uint64 `json:"ext_net_id"` - ExtNetIP string `json:"ext_net_ip"` - ExtNetMask uint64 `json:"ext_netmask"` - QOS QOS `json:"qos"` -} - -type Devices struct { - Primary DevicePrimary `json:"primary"` -} - -type DevicePrimary struct { - DevID uint64 `json:"devId"` - IFace01 string `json:"iface01"` - IFace02 string `json:"iface02"` -} - -type DHCP struct { - CKey string `json:"_ckey"` - AccountID uint64 `json:"accountId"` - Config DHCPConfig `json:"config"` - CreatedTime uint64 `json:"createdTime"` - Devices Devices `json:"devices"` - GID uint64 `json:"gid"` - GUID uint64 `json:"guid"` - ID uint64 `json:"id"` - LockStatus string `json:"lockStatus"` - Milestones uint64 `json:"milestones"` - OwnerID uint64 `json:"ownerId"` - OwnerType string `json:"ownerType"` - PureVirtual bool `json:"pureVirtual"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` -} - -type DHCPConfig struct { - DefaultGW string `json:"default_gw"` - DNS []string `json:"dns"` - IPEnd string `json:"ip_end"` - IPStart string `json:"ip_start"` - Lease uint64 `json:"lease"` - Netmask uint64 `json:"netmask"` - Network string `json:"network"` - Reservations ReservationList `json:"reservations"` -} - -type VINSDetailed struct { - VNFDev VNFDev `json:"VNFDev"` - CKey string `json:"_ckey"` - AccountID uint64 `json:"accountId"` - AccountName string `json:"accountName"` - Computes VINSComputeList `json:"computes"` - DefaultGW string `json:"defaultGW"` - DefaultQOS QOS `json:"defaultQos"` - Description string `json:"desc"` - GID uint64 `json:"gid"` - GUID uint64 `json:"guid"` - ID uint64 `json:"id"` - LockStatus string `json:"lockStatus"` - ManagerID uint64 `json:"managerId"` - ManagerType string `json:"managerType"` - Milestones uint64 `json:"milestones"` - Name string `json:"name"` - NetMask uint64 `json:"netMask"` - Network string `json:"network"` - PreReservaionsNum uint64 `json:"preReservationsNum"` - Redundant bool `json:"redundant"` - RGID uint64 `json:"rgId"` - RGName string `json:"rgName"` - SecVNFDevID uint64 `json:"secVnfDevId"` - Status string `json:"status"` - UserManaged bool `json:"userManaged"` - VNFS VNFS `json:"vnfs"` - VXLanID uint64 `json:"vxlanId"` -} - -type Reservation struct { - ClientType string `json:"clientType"` - Description string `json:"desc"` - DomainName string `json:"domainname"` - HostName string `json:"hostname"` - IP string `json:"ip"` - MAC string `json:"mac"` - Type string `json:"type"` - VMID int `json:"vmId"` -} - -type ReservationList []Reservation - -type NATRule struct { - ID uint64 `json:"id"` - LocalIP string `json:"localIp"` - LocalPort uint64 `json:"localPort"` - Protocol string `json:"protocol"` - PublicPortEnd uint64 `json:"publicPortEnd"` - PublicPortStart uint64 `json:"publicPortStart"` - VMID uint64 `json:"vmId"` - VMName string `json:"vmName"` -} - -type NATRuleList []NATRule diff --git a/internal/service/cloudapi/vins/resource_check_input_values.go b/internal/service/cloudapi/vins/resource_check_input_values.go index 4a67915..a1fb8e4 100644 --- a/internal/service/cloudapi/vins/resource_check_input_values.go +++ b/internal/service/cloudapi/vins/resource_check_input_values.go @@ -2,43 +2,26 @@ package vins import ( "context" - "encoding/json" - "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + rgId := uint64(d.Get("rg_id").(int)) + req := rg.ListRequest{} - rgList := []struct { - ID int `json:"id"` - }{} - - rgListAPI := "/restmachine/cloudapi/rg/list" - - rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues) + rgList, err := c.CloudAPI().RG().List(ctx, req) if err != nil { return false, err } - err = json.Unmarshal([]byte(rgListRaw), &rgList) - if err != nil { - return false, err - } - - haveRG := false - rgId := d.Get("rg_id").(int) - for _, rg := range rgList { - if rg.ID == rgId { - haveRG = true - break - } - } - - return haveRG, nil + return len(rgList.FilterByID(rgId)) != 0, nil } func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { @@ -49,98 +32,39 @@ func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) ( } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - extNetList := []struct { - ID int `json:"id"` - }{} + extNetIDParsed := uint64(extNetID) + req := extnet.ListRequest{} - extNetListAPI := "/restmachine/cloudapi/extnet/list" - - extNetListRaw, err := c.DecortAPICall(ctx, "POST", extNetListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(extNetListRaw), &extNetList) + extNetList, err := c.CloudAPI().ExtNet().List(ctx, req) if err != nil { return false, err } - haveExtNet := false - for _, extNet := range extNetList { - if extNet.ID == extNetID { - haveExtNet = true - break - } - } - - return haveExtNet, nil + return len(extNetList.FilterByID(extNetIDParsed)) != 0, nil } func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + accountId := uint64(d.Get("account_id").(int)) + req := account.ListRequest{} - urlValues := &url.Values{} - - accountList := []struct { - ID int `json:"id"` - }{} - - accountListAPI := "/restmachine/cloudapi/account/list" - - accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(accountListRaw), &accountList) + accountList, err := c.CloudAPI().Account().List(ctx, req) if err != nil { return false, err } - haveAccount := false - - myAccount := d.Get("account_id").(int) - for _, account := range accountList { - if account.ID == myAccount { - haveAccount = true - break - } - } - return haveAccount, nil + return len(accountList.FilterByID(accountId)) != 0, nil } func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) { c := m.(*controller.ControllerCfg) + gid := uint64(d.Get("gid").(int)) + req := locations.ListRequest{} - urlValues := &url.Values{} - - locationList := []struct { - GID int `json:"gid"` - }{} - - locationsListAPI := "/restmachine/cloudapi/locations/list" - - locationListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues) - if err != nil { - return false, err - } - - err = json.Unmarshal([]byte(locationListRaw), &locationList) + locationList, err := c.CloudAPI().Locations().List(ctx, req) if err != nil { return false, err } - haveGID := false - - gid := d.Get("gid").(int) - for _, location := range locationList { - if location.GID == gid { - haveGID = true - break - } - } - - return haveGID, nil + return len(locationList.FilterByGID(gid)) != 0, nil } diff --git a/internal/service/cloudapi/vins/resource_vins.go b/internal/service/cloudapi/vins/resource_vins.go index 9205cef..26d5698 100644 --- a/internal/service/cloudapi/vins/resource_vins.go +++ b/internal/service/cloudapi/vins/resource_vins.go @@ -34,11 +34,10 @@ package vins import ( "context" - "fmt" - "net/url" "strconv" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc" @@ -51,7 +50,6 @@ import ( func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} if _, ok := d.GetOk("rg_id"); ok { haveRGID, err := existRGID(ctx, d, m) @@ -104,97 +102,111 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface } if rgOk { - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("rgId", strconv.Itoa(rgId.(int))) + req := vins.CreateInRGRequest{ + Name: d.Get("name").(string), + RGID: uint64(rgId.(int)), + } + if ipcidr, ok := d.GetOk("ipcidr"); ok { - urlValues.Add("ipcidr", ipcidr.(string)) + req.IPCIDR = ipcidr.(string) } //extnet v1 - urlValues.Add("extNetId", strconv.Itoa(d.Get("ext_net_id").(int))) + req.ExtNetID = uint64(d.Get("ext_net_id").(int)) if extIp, ok := d.GetOk("ext_ip_addr"); ok { - urlValues.Add("extIp", extIp.(string)) + req.ExtIP = extIp.(string) } //extnet v2 if extNetResp, ok := d.GetOk("ext_net"); ok { extNetSl := extNetResp.([]interface{}) extNet := extNetSl[0].(map[string]interface{}) - urlValues.Add("vinsId", d.Id()) - urlValues.Add("netId", strconv.Itoa(extNet["ext_net_id"].(int))) - urlValues.Add("extIp", extNet["ext_net_ip"].(string)) + + req.ExtNetID = uint64(extNet["ext_net_id"].(int)) + req.ExtIP = extNet["ext_net_ip"].(string) } if desc, ok := d.GetOk("desc"); ok { - urlValues.Add("desc", desc.(string)) + req.Description = desc.(string) } - urlValues.Add("preReservationsNum", strconv.Itoa(d.Get("pre_reservations_num").(int))) - id, err := c.DecortAPICall(ctx, "POST", VinsCreateInRgAPI, urlValues) + req.PreReservationsNum = uint(d.Get("pre_reservations_num").(int)) + + id, err := c.CloudAPI().VINS().CreateInRG(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(id) + + d.SetId(strconv.FormatUint(id, 10)) } else if accountIdOk { - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req := vins.CreateInAccountRequest{ + Name: d.Get("name").(string), + AccountID: uint64(accountId.(int)), + PreReservationsNum: uint64(d.Get("pre_reservations_num").(int)), + } + if gid, ok := d.GetOk("gid"); ok { - urlValues.Add("gid", strconv.Itoa(gid.(int))) + req.GID = uint64(gid.(int)) } if ipcidr, ok := d.GetOk("ipcidr"); ok { - urlValues.Add("ipcidr", ipcidr.(string)) + req.IPCIDR = ipcidr.(string) } if desc, ok := d.GetOk("desc"); ok { - urlValues.Add("desc", desc.(string)) + req.Description = desc.(string) } - urlValues.Add("preReservationsNum", strconv.Itoa(d.Get("pre_reservations_num").(int))) - id, err := c.DecortAPICall(ctx, "POST", VinsCreateInAccountAPI, urlValues) + + id, err := c.CloudAPI().VINS().CreateInAccount(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(id) + + d.SetId(strconv.FormatUint(id, 10)) } + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + warnings := dc.Warnings{} - urlValues = &url.Values{} if ipRes, ok := d.GetOk("ip"); ok { ipsSlice := ipRes.([]interface{}) for _, ipInterfase := range ipsSlice { ip := ipInterfase.(map[string]interface{}) - urlValues = &url.Values{} - urlValues.Add("vinsId", d.Id()) - urlValues.Add("type", ip["type"].(string)) + + req := vins.IPReserveRequest{ + VINSID: vinsId, + Type: ip["type"].(string), + } + if ipAddr, ok := ip["ip_addr"]; ok { - urlValues.Add("ipAddr", ipAddr.(string)) + req.IPAddr = ipAddr.(string) } if macAddr, ok := ip["mac_addr"]; ok { - urlValues.Add("mac", macAddr.(string)) + req.MAC = macAddr.(string) } if computeId, ok := ip["compute_id"]; ok { - urlValues.Add("computeId", strconv.Itoa(computeId.(int))) + req.ComputeID = uint64(computeId.(int)) } - _, err := c.DecortAPICall(ctx, "POST", VinsIpReserveAPI, urlValues) + _, err := c.CloudAPI().VINS().IPReserve(ctx, req) if err != nil { warnings.Add(err) } } } - urlValues = &url.Values{} if natRule, ok := d.GetOk("nat_rule"); ok { addedNatRules := natRule.([]interface{}) if len(addedNatRules) > 0 { for _, natRuleInterface := range addedNatRules { - urlValues = &url.Values{} natRule := natRuleInterface.(map[string]interface{}) - urlValues.Add("vinsId", d.Id()) - urlValues.Add("intIp", natRule["int_ip"].(string)) - urlValues.Add("intPort", strconv.Itoa(natRule["int_port"].(int))) - urlValues.Add("extPortStart", strconv.Itoa(natRule["ext_port_start"].(int))) - urlValues.Add("extPortEnd", strconv.Itoa(natRule["ext_port_end"].(int))) - urlValues.Add("proto", natRule["proto"].(string)) + req := vins.NATRuleAddRequest{ + VINSID: vinsId, + IntIP: natRule["int_ip"].(string), + IntPort: uint(natRule["int_port"].(int)), + ExtPortStart: uint(natRule["ext_port_start"].(int)), + ExtPortEnd: uint(natRule["ext_port_end"].(int)), + Proto: natRule["proto"].(string), + } - _, err := c.DecortAPICall(ctx, "POST", VinsNatRuleAddAPI, urlValues) + _, err := c.CloudAPI().VINS().NATRuleAdd(ctx, req) if err != nil { warnings.Add(err) } @@ -210,7 +222,7 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{} c := m.(*controller.ControllerCfg) warnings := dc.Warnings{} - vins, err := utilityVinsCheckPresence(ctx, d, m) + vinsData, err := utilityVinsCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) @@ -220,32 +232,33 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{} hasChangeState := false - switch vins.Status { + switch vinsData.Status { case status.Destroyed: - d.SetId("") d.Set("vins_id", 0) + d.SetId("") return resourceVinsCreate(ctx, d, m) case status.Deleted: hasChangeState = true - urlValues := &url.Values{} - urlValues.Add("vinsId", d.Id()) + req := vins.RestoreRequest{ + VINSID: vinsData.ID, + } - _, err := c.DecortAPICall(ctx, "POST", VinsRestoreAPI, urlValues) + _, err := c.CloudAPI().VINS().Restore(ctx, req) if err != nil { warnings.Add(err) } case status.Modeled: - return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vins.Status) + return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status) case status.Created: case status.Enabled: if !isEnabled { hasChangeState = true - urlValues := &url.Values{} - - urlValues.Add("vinsId", d.Id()) + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } - _, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues) + _, err := c.CloudAPI().VINS().Disable(ctx, req) if err != nil { warnings.Add(err) } @@ -254,29 +267,29 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{} case status.Disabled: if isEnabled { hasChangeState = true - urlValues := &url.Values{} - - urlValues.Add("vinsId", d.Id()) + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } - _, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues) + _, err := c.CloudAPI().VINS().Enable(ctx, req) if err != nil { warnings.Add(err) } } case status.Disabling: case status.Deleting: - return diag.Errorf("ViNS are in progress with status: %s", vins.Status) + return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status) } if hasChangeState { - vins, err = utilityVinsCheckPresence(ctx, d, m) + vinsData, err = utilityVinsCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } } - flattenVins(d, *vins) + flattenVins(d, *vinsData) return warnings.Get() } @@ -292,7 +305,7 @@ func isContainsIp(els []interface{}, el interface{}) bool { return false } -func isContinsNatRule(els []interface{}, el interface{}) bool { +func isContainsNatRule(els []interface{}, el interface{}) bool { for _, elOld := range els { elOldConv := elOld.(map[string]interface{}) elConv := el.(map[string]interface{}) @@ -353,7 +366,7 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface } } - vins, err := utilityVinsCheckPresence(ctx, d, m) + vinsData, err := utilityVinsCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) @@ -363,31 +376,32 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface hasChangeState := false - switch vins.Status { + switch vinsData.Status { case status.Destroyed: d.SetId("") return resourceVinsCreate(ctx, d, m) case status.Deleted: hasChangeState = true - urlValues := &url.Values{} - urlValues.Add("vinsId", d.Id()) + req := vins.RestoreRequest{ + VINSID: vinsData.ID, + } - _, err := c.DecortAPICall(ctx, "POST", VinsRestoreAPI, urlValues) + _, err := c.CloudAPI().VINS().Restore(ctx, req) if err != nil { warnings.Add(err) } case status.Modeled: - return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vins.Status) + return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status) case status.Created: case status.Enabled: if !isEnabled { hasChangeState = true - urlValues := &url.Values{} - - urlValues.Add("vinsId", d.Id()) + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } - _, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues) + _, err := c.CloudAPI().VINS().Disable(ctx, req) if err != nil { warnings.Add(err) } @@ -396,43 +410,44 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface case status.Disabled: if isEnabled { hasChangeState = true - urlValues := &url.Values{} - - urlValues.Add("vinsId", d.Id()) + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, + } - _, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues) + _, err := c.CloudAPI().VINS().Enable(ctx, req) if err != nil { warnings.Add(err) } } case status.Disabling: case status.Deleting: - return diag.Errorf("ViNS are in progress with status: %s", vins.Status) + return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status) } if hasChangeState { - vins, err = utilityVinsCheckPresence(ctx, d, m) + vinsData, err = utilityVinsCheckPresence(ctx, d, m) if err != nil { d.SetId("") return diag.FromErr(err) } } - urlValues := &url.Values{} enableOld, enableNew := d.GetChange("enable") if enableOld.(bool) && !enableNew.(bool) { - if !urlValues.Has("vinsId") { - urlValues.Add("vinsId", d.Id()) + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, } - _, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues) + + _, err := c.CloudAPI().VINS().Disable(ctx, req) if err != nil { warnings.Add(err) } } else if !enableOld.(bool) && enableNew.(bool) { - if !urlValues.Has("vinsId") { - urlValues.Add("vinsId", d.Id()) + req := vins.DisableEnableRequest{ + VINSID: vinsData.ID, } - _, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues) + + _, err := c.CloudAPI().VINS().Enable(ctx, req) if err != nil { warnings.Add(err) } @@ -443,12 +458,11 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface if oldExtNetId.(int) != newExtNedId.(int) { log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int)) - extnetParams := &url.Values{} - extnetParams.Add("vinsId", d.Id()) - if oldExtNetId.(int) > 0 { // there was preexisting external net connection - disconnect ViNS - _, err := c.DecortAPICall(ctx, "POST", VinsExtNetDisconnectAPI, extnetParams) + req := vins.ExtNetDisconnectRequest{VINSID: vinsData.ID} + + _, err := c.CloudAPI().VINS().ExtNetDisconnect(ctx, req) if err != nil { warnings.Add(err) } @@ -456,19 +470,24 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface if newExtNedId.(int) > 0 { // new external network connection requested - connect ViNS - extnetParams.Add("netId", fmt.Sprintf("%d", newExtNedId.(int))) + req := vins.ExtNetConnectRequest{ + VINSID: vinsData.ID, + NetID: uint64(newExtNedId.(int)), + IP: "", + } + extNetIp, ok := d.GetOk("ext_net_ip") if ok && extNetIp.(string) != "" { - urlValues.Add("Ip", extNetIp.(string)) + req.IP = extNetIp.(string) } - _, err := c.DecortAPICall(ctx, "POST", VinsExtNetConnectAPI, extnetParams) + + _, err := c.CloudAPI().VINS().ExtNetConnect(ctx, req) if err != nil { warnings.Add(err) } } } - urlValues = &url.Values{} if d.HasChange("ip") { deletedIps := make([]interface{}, 0) addedIps := make([]interface{}, 0) @@ -491,17 +510,17 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface if len(deletedIps) > 0 { for _, ipInterfase := range deletedIps { - urlValues = &url.Values{} ip := ipInterfase.(map[string]interface{}) + req := vins.IPReleaseRequest{VINSID: vinsData.ID} - urlValues.Add("vinsId", d.Id()) if ip["ip_addr"].(string) != "" { - urlValues.Add("ipAddr", ip["ip_addr"].(string)) + req.IPAddr = ip["ip_addr"].(string) } if ip["mac_addr"].(string) != "" { - urlValues.Add("mac", ip["mac_addr"].(string)) + req.MAC = ip["mac_addr"].(string) } - _, err := c.DecortAPICall(ctx, "POST", VinsIpReleaseAPI, urlValues) + + _, err := c.CloudAPI().VINS().IPRelese(ctx, req) if err != nil { warnings.Add(err) } @@ -510,21 +529,23 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface if len(addedIps) > 0 { for _, ipInterfase := range addedIps { - urlValues = &url.Values{} ip := ipInterfase.(map[string]interface{}) + req := vins.IPReserveRequest{ + VINSID: vinsData.ID, + Type: ip["type"].(string), + } - urlValues.Add("vinsId", d.Id()) - urlValues.Add("type", ip["type"].(string)) if ip["ip_addr"].(string) != "" { - urlValues.Add("ipAddr", ip["ip_addr"].(string)) + req.IPAddr = ip["ip_addr"].(string) } if ip["mac_addr"].(string) != "" { - urlValues.Add("mac", ip["mac_addr"].(string)) + req.MAC = ip["mac_addr"].(string) } if ip["compute_id"].(int) != 0 { - urlValues.Add("computeId", strconv.Itoa(ip["compute_id"].(int))) + req.ComputeID = uint64(ip["compute_id"].(int)) } - _, err := c.DecortAPICall(ctx, "POST", VinsIpReserveAPI, urlValues) + + _, err := c.CloudAPI().VINS().IPReserve(ctx, req) if err != nil { warnings.Add(err) } @@ -541,26 +562,26 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface newNatRulesSlice := newNatRulesInterface.([]interface{}) for _, el := range oldNatRulesSlice { - if !isContinsNatRule(newNatRulesSlice, el) { + if !isContainsNatRule(newNatRulesSlice, el) { deletedNatRules = append(deletedNatRules, el) } } for _, el := range newNatRulesSlice { - if !isContinsNatRule(oldNatRulesSlice, el) { + if !isContainsNatRule(oldNatRulesSlice, el) { addedNatRules = append(addedNatRules, el) } } if len(deletedNatRules) > 0 { for _, natRuleInterface := range deletedNatRules { - urlValues = &url.Values{} natRule := natRuleInterface.(map[string]interface{}) + req := vins.NATRuleDelRequest{ + VINSID: vinsData.ID, + RuleID: uint64(natRule["rule_id"].(int)), + } - urlValues.Add("vinsId", d.Id()) - urlValues.Add("ruleId", strconv.Itoa(natRule["rule_id"].(int))) - log.Debug("NAT_RULE_DEL_WITH: ", urlValues.Encode()) - _, err := c.DecortAPICall(ctx, "POST", VinsNatRuleDelAPI, urlValues) + _, err := c.CloudAPI().VINS().NATRuleDel(ctx, req) if err != nil { warnings.Add(err) } @@ -569,22 +590,22 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface if len(addedNatRules) > 0 { for _, natRuleInterface := range addedNatRules { - urlValues = &url.Values{} natRule := natRuleInterface.(map[string]interface{}) + req := vins.NATRuleAddRequest{ + VINSID: vinsData.ID, + IntIP: natRule["int_ip"].(string), + IntPort: uint(natRule["int_port"].(int)), + ExtPortStart: uint(natRule["ext_port_start"].(int)), + } - urlValues.Add("vinsId", d.Id()) - urlValues.Add("intIp", natRule["int_ip"].(string)) - urlValues.Add("intPort", strconv.Itoa(natRule["int_port"].(int))) - urlValues.Add("extPortStart", strconv.Itoa(natRule["ext_port_start"].(int))) if natRule["ext_port_end"].(int) != 0 { - urlValues.Add("extPortEnd", strconv.Itoa(natRule["ext_port_end"].(int))) + req.ExtPortEnd = uint(natRule["ext_port_end"].(int)) } if natRule["proto"].(string) != "" { - urlValues.Add("proto", natRule["proto"].(string)) + req.Proto = natRule["proto"].(string) } - log.Debug("NAT_RULE_ADD_WITH: ", urlValues.Encode()) - _, err := c.DecortAPICall(ctx, "POST", VinsNatRuleAddAPI, urlValues) + _, err := c.CloudAPI().VINS().NATRuleAdd(ctx, req) if err != nil { warnings.Add(err) } @@ -593,18 +614,18 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface } if oldRestart, newRestart := d.GetChange("vnfdev_restart"); oldRestart == false && newRestart == true { - urlValues = &url.Values{} - urlValues.Add("vinsId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", VinsVnfdevRestartAPI, urlValues) + req := vins.VNFDevRestartRequest{VINSID: vinsData.ID} + + _, err := c.CloudAPI().VINS().VNFDevRestart(ctx, req) if err != nil { warnings.Add(err) } } if oldRedeploy, newRedeploy := d.GetChange("vnfdev_redeploy"); oldRedeploy == false && newRedeploy == true { - urlValues = &url.Values{} - urlValues.Add("vinsId", d.Id()) - _, err := c.DecortAPICall(ctx, "POST", VinsVnfdevRedeployAPI, urlValues) + req := vins.VNFDevRedeployRequest{VINSID: vinsData.ID} + + _, err := c.CloudAPI().VINS().VNFDevRedeploy(ctx, req) if err != nil { warnings.Add(err) } @@ -615,16 +636,21 @@ func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface } func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - urlValues := &url.Values{} c := m.(*controller.ControllerCfg) + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := vins.DeleteRequest{ + VINSID: vinsId, + Force: d.Get("force").(bool), + Permanently: d.Get("permanently").(bool), + } - urlValues.Add("vinsId", d.Id()) - urlValues.Add("force", strconv.FormatBool(d.Get("force").(bool))) - urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) - _, err := c.DecortAPICall(ctx, "POST", VinsDeleteAPI, urlValues) + _, err := c.CloudAPI().VINS().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + + d.SetId("") + return nil } diff --git a/internal/service/cloudapi/vins/utility_vins.go b/internal/service/cloudapi/vins/utility_vins.go index 8535f88..3f82826 100644 --- a/internal/service/cloudapi/vins/utility_vins.go +++ b/internal/service/cloudapi/vins/utility_vins.go @@ -34,49 +34,39 @@ package vins import ( "context" - "encoding/json" - "net/url" "strconv" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityDataVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) { +func utilityDataVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.RecordVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - vins := &VINSDetailed{} - - urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int))) - vinsRaw, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues) - if err != nil { - return nil, err + req := vins.GetRequest{ + VINSID: uint64(d.Get("vins_id").(int)), } - err = json.Unmarshal([]byte(vinsRaw), vins) + vins, err := c.CloudAPI().VINS().Get(ctx, req) if err != nil { return nil, err } - return vins, nil + return vins, nil } -func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VINSDetailed, error) { +func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.RecordVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - vins := &VINSDetailed{} - - urlValues.Add("vinsId", d.Id()) - vinsRaw, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues) - if err != nil { - return nil, err + vinsId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := vins.GetRequest{ + VINSID: vinsId, } - err = json.Unmarshal([]byte(vinsRaw), vins) + vins, err := c.CloudAPI().VINS().Get(ctx, req) if err != nil { return nil, err } - return vins, nil + return vins, nil } diff --git a/internal/service/cloudapi/vins/utility_vins_audits.go b/internal/service/cloudapi/vins/utility_vins_audits.go index 67af263..a12d733 100644 --- a/internal/service/cloudapi/vins/utility_vins_audits.go +++ b/internal/service/cloudapi/vins/utility_vins_audits.go @@ -34,28 +34,22 @@ package vins import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityVinsAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSAuditsList, error) { +func utilityVinsAuditsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListAudits, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - auditsList := VINSAuditsList{} - - urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int))) - auidtsRaw, err := c.DecortAPICall(ctx, "POST", VinsAuditsAPI, urlValues) - if err != nil { - return nil, err + req := vins.AuditsRequest{ + VINSID: uint64(d.Get("vins_id").(int)), } - err = json.Unmarshal([]byte(auidtsRaw), &auditsList) + audits, err := c.CloudAPI().VINS().Audits(ctx, req) if err != nil { return nil, err } - return auditsList, nil + + return audits, nil } diff --git a/internal/service/cloudapi/vins/utility_vins_ext_net_list.go b/internal/service/cloudapi/vins/utility_vins_ext_net_list.go index e9b716f..3e3e7f3 100644 --- a/internal/service/cloudapi/vins/utility_vins_ext_net_list.go +++ b/internal/service/cloudapi/vins/utility_vins_ext_net_list.go @@ -34,28 +34,22 @@ package vins import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityVinsExtNetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ExtNetList, error) { +func utilityVinsExtNetListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListExtNets, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - extNet := ExtNetList{} - - urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int))) - extNetRaw, err := c.DecortAPICall(ctx, "POST", VinsExtNetListAPI, urlValues) - if err != nil { - return nil, err + req := vins.ExtNetListRequest{ + VINSID: uint64(d.Get("vins_id").(int)), } - err = json.Unmarshal([]byte(extNetRaw), &extNet) + extNetList, err := c.CloudAPI().VINS().ExtNetList(ctx, req) if err != nil { return nil, err } - return extNet, nil + + return extNetList, nil } diff --git a/internal/service/cloudapi/vins/utility_vins_ip_list.go b/internal/service/cloudapi/vins/utility_vins_ip_list.go index b061825..614ebbe 100644 --- a/internal/service/cloudapi/vins/utility_vins_ip_list.go +++ b/internal/service/cloudapi/vins/utility_vins_ip_list.go @@ -34,28 +34,22 @@ package vins import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityVinsIpListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (IPList, error) { +func utilityVinsIpListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListIPs, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - ips := IPList{} - - urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int))) - auidtsRaw, err := c.DecortAPICall(ctx, "POST", VinsIpListAPI, urlValues) - if err != nil { - return nil, err + req := vins.IPListRequest{ + VINSID: uint64(d.Get("vins_id").(int)), } - err = json.Unmarshal([]byte(auidtsRaw), &ips) + ips, err := c.CloudAPI().VINS().IPList(ctx, req) if err != nil { return nil, err } + return ips, nil } diff --git a/internal/service/cloudapi/vins/utility_vins_list.go b/internal/service/cloudapi/vins/utility_vins_list.go index 6419590..a00c20b 100644 --- a/internal/service/cloudapi/vins/utility_vins_list.go +++ b/internal/service/cloudapi/vins/utility_vins_list.go @@ -34,38 +34,30 @@ package vins import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSList, error) { - vinsList := VINSList{} +func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := vins.ListRequest{} if includeDeleted, ok := d.GetOk("include_deleted"); ok { - urlValues.Add("includeDeleted", strconv.FormatBool(includeDeleted.(bool))) + req.IncludeDeleted = includeDeleted.(bool) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityVinsListCheckPresence") - vinsListRaw, err := c.DecortAPICall(ctx, "POST", VinsListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(vinsListRaw), &vinsList) + vinsList, err := c.CloudAPI().VINS().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/vins/utility_vins_list_deleted.go b/internal/service/cloudapi/vins/utility_vins_list_deleted.go index df8bd3e..92db68a 100644 --- a/internal/service/cloudapi/vins/utility_vins_list_deleted.go +++ b/internal/service/cloudapi/vins/utility_vins_list_deleted.go @@ -34,34 +34,26 @@ package vins import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityVinsListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VINSList, error) { - vinsList := VINSList{} +func utilityVinsListDeletedCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := vins.ListDeletedRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityVinsListDeletedCheckPresence") - vinsListRaw, err := c.DecortAPICall(ctx, "POST", VinsListDeletedAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(vinsListRaw), &vinsList) + vinsList, err := c.CloudAPI().VINS().ListDeleted(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go b/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go index ebe36f4..5e3c283 100644 --- a/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go +++ b/internal/service/cloudapi/vins/utility_vins_nat_rule_list.go @@ -34,28 +34,22 @@ package vins import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityVinsNatRuleListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (NATRuleList, error) { +func utilityVinsNatRuleListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListNATRules, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - natRuleList := NATRuleList{} - - urlValues.Add("vinsId", strconv.Itoa(d.Get("vins_id").(int))) - auidtsRaw, err := c.DecortAPICall(ctx, "POST", VinsNatRuleListAPI, urlValues) - if err != nil { - return nil, err + req := vins.NATRuleListRequest{ + VINSID: uint64(d.Get("vins_id").(int)), } - err = json.Unmarshal([]byte(auidtsRaw), &natRuleList) + natRuleList, err := c.CloudAPI().VINS().NATRuleList(ctx, req) if err != nil { return nil, err } + return natRuleList, nil } diff --git a/internal/service/cloudbroker/account/account_ds.go b/internal/service/cloudbroker/account/account_ds.go index 432853a..61d6205 100644 --- a/internal/service/cloudbroker/account/account_ds.go +++ b/internal/service/cloudbroker/account/account_ds.go @@ -119,13 +119,13 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, Computed: true, }, - "meta": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, + // "meta": { + // Type: schema.TypeList, + // Computed: true, + // Elem: &schema.Schema{ + // Type: schema.TypeString, + // }, + // }, "acl": { Type: schema.TypeList, Computed: true, @@ -234,10 +234,10 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema { Type: schema.TypeBool, Computed: true, }, - "service_account": { - Type: schema.TypeBool, - Computed: true, - }, + // "service_account": { + // Type: schema.TypeBool, + // Computed: true, + // }, "status": { Type: schema.TypeString, Computed: true, diff --git a/internal/service/cloudbroker/account/account_rs.go b/internal/service/cloudbroker/account/account_rs.go index f33634d..97775f4 100644 --- a/internal/service/cloudbroker/account/account_rs.go +++ b/internal/service/cloudbroker/account/account_rs.go @@ -218,13 +218,13 @@ func resourceAccountSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, Computed: true, }, - "meta": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, + // "meta": { + // Type: schema.TypeList, + // Computed: true, + // Elem: &schema.Schema{ + // Type: schema.TypeString, + // }, + // }, "acl": { Type: schema.TypeList, Computed: true, @@ -293,10 +293,10 @@ func resourceAccountSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, - "service_account": { - Type: schema.TypeBool, - Computed: true, - }, + // "service_account": { + // Type: schema.TypeBool, + // Computed: true, + // }, "status": { Type: schema.TypeString, Computed: true, diff --git a/internal/service/cloudbroker/account/data_source_account.go b/internal/service/cloudbroker/account/data_source_account.go index 0bf0288..a46df59 100644 --- a/internal/service/cloudbroker/account/data_source_account.go +++ b/internal/service/cloudbroker/account/data_source_account.go @@ -33,12 +33,11 @@ package account import ( "context" + "strconv" - "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -47,51 +46,12 @@ func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interf return diag.FromErr(err) } - id := uuid.New() - d.SetId(id.String()) - d.Set("dc_location", acc.DCLocation) - d.Set("resources", flattenAccResources(acc.Resources)) - d.Set("ckey", acc.CKey) - d.Set("meta", flattens.FlattenMeta(acc.Meta)) - d.Set("acl", flattenAccAcl(acc.Acl)) - d.Set("company", acc.Company) - d.Set("companyurl", acc.CompanyUrl) - d.Set("created_by", acc.CreatedBy) - d.Set("created_time", acc.CreatedTime) - d.Set("deactivation_time", acc.DeactiovationTime) - d.Set("deleted_by", acc.DeletedBy) - d.Set("deleted_time", acc.DeletedTime) - d.Set("displayname", acc.DisplayName) - d.Set("guid", acc.GUID) - d.Set("account_id", acc.ID) - d.Set("account_name", acc.Name) - d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) - d.Set("send_access_emails", acc.SendAccessEmails) - d.Set("service_account", acc.ServiceAccount) - d.Set("status", acc.Status) - d.Set("updated_time", acc.UpdatedTime) - d.Set("version", acc.Version) - d.Set("vins", acc.Vins) + d.SetId(strconv.FormatUint(acc.ID, 10)) + flattenDataAccount(d, acc) return nil } -func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, acls := range acls { - temp := map[string]interface{}{ - "explicit": acls.IsExplicit, - "guid": acls.Guid, - "right": acls.Rights, - "status": acls.Status, - "type": acls.Type, - "user_group_id": acls.UgroupID, - } - res = append(res, temp) - } - return res -} - func DataSourceAccount() *schema.Resource { return &schema.Resource{ SchemaVersion: 1, diff --git a/internal/service/cloudbroker/account/data_source_account_audits_list.go b/internal/service/cloudbroker/account/data_source_account_audits_list.go index 4b72a77..3474cdb 100644 --- a/internal/service/cloudbroker/account/data_source_account_audits_list.go +++ b/internal/service/cloudbroker/account/data_source_account_audits_list.go @@ -40,22 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountAuditsList(aal AccountAuditsList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, aa := range aal { - temp := map[string]interface{}{ - "call": aa.Call, - "responsetime": aa.ResponseTime, - "statuscode": aa.StatusCode, - "timestamp": aa.Timestamp, - "user": aa.User, - } - res = append(res, temp) - } - return res - -} - func dataSourceAccountAuditsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { accountAuditsList, err := utilityAccountAuditsListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/account/data_source_account_computes_list.go b/internal/service/cloudbroker/account/data_source_account_computes_list.go index ae5372c..1512336 100644 --- a/internal/service/cloudbroker/account/data_source_account_computes_list.go +++ b/internal/service/cloudbroker/account/data_source_account_computes_list.go @@ -40,37 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountComputesList(acl AccountComputesList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, acc := range acl { - temp := map[string]interface{}{ - "account_id": acc.AccountId, - "account_name": acc.AccountName, - "cpus": acc.CPUs, - "created_by": acc.CreatedBy, - "created_time": acc.CreatedTime, - "deleted_by": acc.DeletedBy, - "deleted_time": acc.DeletedTime, - "compute_id": acc.ComputeId, - "compute_name": acc.ComputeName, - "ram": acc.RAM, - "registered": acc.Registered, - "rg_id": acc.RgId, - "rg_name": acc.RgName, - "status": acc.Status, - "tech_status": acc.TechStatus, - "total_disks_size": acc.TotalDisksSize, - "updated_by": acc.UpdatedBy, - "updated_time": acc.UpdatedTime, - "user_managed": acc.UserManaged, - "vins_connected": acc.VinsConnected, - } - res = append(res, temp) - } - return res - -} - func dataSourceAccountComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { accountComputesList, err := utilityAccountComputesListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/account/data_source_account_disks_list.go b/internal/service/cloudbroker/account/data_source_account_disks_list.go index f29e552..5df1c6e 100644 --- a/internal/service/cloudbroker/account/data_source_account_disks_list.go +++ b/internal/service/cloudbroker/account/data_source_account_disks_list.go @@ -39,23 +39,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountDisksList(adl AccountDisksList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, ad := range adl { - temp := map[string]interface{}{ - "disk_id": ad.ID, - "disk_name": ad.Name, - "pool_name": ad.Pool, - "sep_id": ad.SepId, - "size_max": ad.SizeMax, - "type": ad.Type, - } - res = append(res, temp) - } - return res - -} - func dataSourceAccountDisksListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { accountDisksList, err := utilityAccountDisksListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/account/data_source_account_flipgroups_list.go b/internal/service/cloudbroker/account/data_source_account_flipgroups_list.go index ce3af76..0001ac9 100644 --- a/internal/service/cloudbroker/account/data_source_account_flipgroups_list.go +++ b/internal/service/cloudbroker/account/data_source_account_flipgroups_list.go @@ -40,38 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountFlipGroupsList(afgl AccountFlipGroupsList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, afg := range afgl { - temp := map[string]interface{}{ - "account_id": afg.AccountId, - "client_type": afg.ClientType, - "conn_type": afg.ConnType, - "created_by": afg.CreatedBy, - "created_time": afg.CreatedTime, - "default_gw": afg.DefaultGW, - "deleted_by": afg.DeletedBy, - "deleted_time": afg.DeletedTime, - "desc": afg.Desc, - "gid": afg.GID, - "guid": afg.GUID, - "fg_id": afg.ID, - "ip": afg.IP, - "milestones": afg.Milestones, - "fg_name": afg.Name, - "net_id": afg.NetID, - "net_type": afg.NetType, - "netmask": afg.NetMask, - "status": afg.Status, - "updated_by": afg.UpdatedBy, - "updated_time": afg.UpdatedTime, - } - res = append(res, temp) - } - return res - -} - func dataSourceAccountFlipGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/account/data_source_account_list.go b/internal/service/cloudbroker/account/data_source_account_list.go index 13c05f4..ebbcab0 100644 --- a/internal/service/cloudbroker/account/data_source_account_list.go +++ b/internal/service/cloudbroker/account/data_source_account_list.go @@ -38,83 +38,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) -func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, rgAcl := range rgAcls { - temp := map[string]interface{}{ - "explicit": rgAcl.IsExplicit, - "guid": rgAcl.Guid, - "right": rgAcl.Rights, - "status": rgAcl.Status, - "type": rgAcl.Type, - "user_group_id": rgAcl.UgroupID, - } - res = append(res, temp) - } - return res -} - -func flattenAccountList(al AccountList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, acc := range al { - temp := map[string]interface{}{ - "dc_location": acc.DCLocation, - "ckey": acc.CKey, - "meta": flattens.FlattenMeta(acc.Meta), - - "acl": flattenRgAcl(acc.Acl), - - "company": acc.Company, - "companyurl": acc.CompanyUrl, - "created_by": acc.CreatedBy, - - "created_time": acc.CreatedTime, - - "deactivation_time": acc.DeactiovationTime, - "deleted_by": acc.DeletedBy, - - "deleted_time": acc.DeletedTime, - - "displayname": acc.DisplayName, - "guid": acc.GUID, - - "account_id": acc.ID, - "account_name": acc.Name, - - "resource_limits": flattenRgResourceLimits(acc.ResourceLimits), - "send_access_emails": acc.SendAccessEmails, - "service_account": acc.ServiceAccount, - - "status": acc.Status, - "updated_time": acc.UpdatedTime, - - "version": acc.Version, - "vins": acc.Vins, - } - res = append(res, temp) - } - return res -} - -func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "cu_c": rl.CUC, - "cu_d": rl.CUD, - "cu_i": rl.CUI, - "cu_m": rl.CUM, - "cu_np": rl.CUNP, - "gpu_units": rl.GpuUnits, - } - res = append(res, temp) - - return res - -} - func dataSourceAccountListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { accountList, err := utilityAccountListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/account/data_source_account_rg_list.go b/internal/service/cloudbroker/account/data_source_account_rg_list.go index 31d4499..64c8ee7 100644 --- a/internal/service/cloudbroker/account/data_source_account_rg_list.go +++ b/internal/service/cloudbroker/account/data_source_account_rg_list.go @@ -40,75 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountRGList(argl AccountRGList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, arg := range argl { - temp := map[string]interface{}{ - "computes": flattenAccRGComputes(arg.Computes), - "resources": flattenAccRGResources(arg.Resources), - "created_by": arg.CreatedBy, - "created_time": arg.CreatedTime, - "deleted_by": arg.DeletedBy, - "deleted_time": arg.DeletedTime, - "rg_id": arg.RGID, - "milestones": arg.Milestones, - "rg_name": arg.RGName, - "status": arg.Status, - "updated_by": arg.UpdatedBy, - "updated_time": arg.UpdatedTime, - "vinses": arg.Vinses, - } - res = append(res, temp) - } - return res - -} - -func flattenAccRGComputes(argc AccountRGComputes) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "started": argc.Started, - "stopped": argc.Stopped, - } - res = append(res, temp) - return res -} - -func flattenAccRGResources(argr AccountRGResources) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "consumed": flattenAccResource(argr.Consumed), - "limits": flattenAccResource(argr.Limits), - "reserved": flattenAccResource(argr.Reserved), - } - res = append(res, temp) - return res -} - -func flattenAccResources(r Resources) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "current": flattenAccResource(r.Current), - "reserved": flattenAccResource(r.Reserved), - } - res = append(res, temp) - return res -} - -func flattenAccResource(r Resource) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "cpu": r.CPU, - "disksize": r.Disksize, - "extips": r.Extips, - "exttraffic": r.Exttraffic, - "gpu": r.GPU, - "ram": r.RAM, - } - res = append(res, temp) - return res -} - func dataSourceAccountRGListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { accountRGList, err := utilityAccountRGListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/account/data_source_account_vins_list.go b/internal/service/cloudbroker/account/data_source_account_vins_list.go index 960c636..3f088ac 100644 --- a/internal/service/cloudbroker/account/data_source_account_vins_list.go +++ b/internal/service/cloudbroker/account/data_source_account_vins_list.go @@ -40,34 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenAccountVinsList(avl AccountVinsList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, av := range avl { - temp := map[string]interface{}{ - "account_id": av.AccountId, - "account_name": av.AccountName, - "computes": av.Computes, - "created_by": av.CreatedBy, - "created_time": av.CreatedTime, - "deleted_by": av.DeletedBy, - "deleted_time": av.DeletedTime, - "external_ip": av.ExternalIP, - "vin_id": av.ID, - "vin_name": av.Name, - "network": av.Network, - "pri_vnf_dev_id": av.PriVnfDevId, - "rg_id": av.RgId, - "rg_name": av.RgName, - "status": av.Status, - "updated_by": av.UpdatedBy, - "updated_time": av.UpdatedTime, - } - res = append(res, temp) - } - return res - -} - func dataSourceAccountVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { accountVinsList, err := utilityAccountVinsListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/account/flattens.go b/internal/service/cloudbroker/account/flattens.go new file mode 100644 index 0000000..7084d45 --- /dev/null +++ b/internal/service/cloudbroker/account/flattens.go @@ -0,0 +1,363 @@ +package account + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenResourceAccount(d *schema.ResourceData, acc *account.RecordAccount) { + d.Set("dc_location", acc.DCLocation) + d.Set("resources", flattenAccResources(acc.Resources)) + d.Set("ckey", acc.CKey) + d.Set("acl", flattenAccAcl(acc.ACL)) + d.Set("company", acc.Company) + d.Set("companyurl", acc.CompanyURL) + d.Set("created_by", acc.CreatedBy) + d.Set("created_time", acc.CreatedTime) + d.Set("deactivation_time", acc.DeactivationTime) + d.Set("deleted_by", acc.DeletedBy) + d.Set("deleted_time", acc.DeletedTime) + d.Set("displayname", acc.DisplayName) + d.Set("guid", acc.GUID) + d.Set("account_id", acc.ID) + d.Set("account_name", acc.Name) + d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) + d.Set("send_access_emails", acc.SendAccessEmails) + d.Set("status", acc.Status) + d.Set("updated_time", acc.UpdatedTime) + d.Set("version", acc.Version) + d.Set("vins", acc.VINS) +} + +func flattenDataAccount(d *schema.ResourceData, acc *account.RecordAccount) { + d.Set("dc_location", acc.DCLocation) + d.Set("resources", flattenAccResources(acc.Resources)) + d.Set("ckey", acc.CKey) + // d.Set("meta", flattens.FlattenMeta(acc.)) + d.Set("acl", flattenAccAcl(acc.ACL)) + d.Set("company", acc.Company) + d.Set("companyurl", acc.CompanyURL) + d.Set("created_by", acc.CreatedBy) + d.Set("created_time", acc.CreatedTime) + d.Set("deactivation_time", acc.DeactivationTime) + d.Set("deleted_by", acc.DeletedBy) + d.Set("deleted_time", acc.DeletedTime) + d.Set("displayname", acc.DisplayName) + d.Set("guid", acc.GUID) + d.Set("account_id", acc.ID) + d.Set("account_name", acc.Name) + d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) + d.Set("send_access_emails", acc.SendAccessEmails) + // d.Set("service_account", acc.ServiceAccount) + d.Set("status", acc.Status) + d.Set("updated_time", acc.UpdatedTime) + d.Set("version", acc.Version) + d.Set("vins", acc.VINS) + +} + +func flattenAccountRGList(argl account.ListRG) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, arg := range argl { + temp := map[string]interface{}{ + "computes": flattenAccRGComputes(arg.Computes), + "resources": flattenAccRGResources(arg.Resources), + "created_by": arg.CreatedBy, + "created_time": arg.CreatedTime, + "deleted_by": arg.DeletedBy, + "deleted_time": arg.DeletedTime, + "rg_id": arg.ID, + "milestones": arg.Milestones, + "rg_name": arg.Name, + "status": arg.Status, + "updated_by": arg.UpdatedBy, + "updated_time": arg.UpdatedTime, + "vinses": arg.VINSes, + } + res = append(res, temp) + } + return res + +} + +func flattenAccRGComputes(argc account.Computes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "started": argc.Started, + "stopped": argc.Stopped, + } + res = append(res, temp) + return res +} + +func flattenAccRGResources(argr account.RGResuorces) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "consumed": flattenAccConsumed(argr.Consumed), + "limits": flattenAccLimits(argr.Limits), + "reserved": flattenAccResource(argr.Reserved), + } + res = append(res, temp) + return res +} + +func flattenAccResources(r account.RecordResources) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "current": flattenAccResource(r.Current), + "reserved": flattenAccResource(r.Reserved), + } + res = append(res, temp) + return res +} + +func flattenAccConsumed(c account.Consumed) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": c.CPU, + "disksize": c.DiskSize, + "extips": c.ExtIPs, + "exttraffic": c.ExtTraffic, + "gpu": c.GPU, + "ram": c.RAM, + } + res = append(res, temp) + return res +} + +func flattenAccLimits(l account.Limits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": l.CPU, + "disksize": l.DiskSize, + "extips": l.ExtIPs, + "exttraffic": l.ExtTraffic, + "gpu": l.GPU, + "ram": l.RAM, + } + res = append(res, temp) + return res +} + +func flattenAccResource(r account.Resource) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cpu": r.CPU, + "disksize": r.DiskSize, + "extips": r.ExtIPs, + "exttraffic": r.ExtTraffic, + "gpu": r.GPU, + "ram": r.RAM, + } + res = append(res, temp) + return res +} + +func flattenAccAcl(acls []account.ACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, acls := range acls { + temp := map[string]interface{}{ + "explicit": acls.Explicit, + "guid": acls.GUID, + "right": acls.Right, + "status": acls.Status, + "type": acls.Type, + "user_group_id": acls.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenRgResourceLimits(rl account.ResourceLimits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "cu_c": rl.CuC, + "cu_d": rl.CuD, + "cu_i": rl.CuI, + "cu_m": rl.CuM, + "cu_np": rl.CuNP, + "gpu_units": rl.GPUUnits, + } + res = append(res, temp) + + return res +} + +func flattenRgAcl(rgAcls []account.ACL) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, rgAcl := range rgAcls { + temp := map[string]interface{}{ + "explicit": rgAcl.Explicit, + "guid": rgAcl.GUID, + "right": rgAcl.Right, + "status": rgAcl.Status, + "type": rgAcl.Type, + "user_group_id": rgAcl.UserGroupID, + } + res = append(res, temp) + } + return res +} + +func flattenAccountList(al account.ListAccounts) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, acc := range al { + temp := map[string]interface{}{ + "dc_location": acc.DCLocation, + "ckey": acc.CKey, + "meta": flattens.FlattenMeta(acc.Meta), + + "acl": flattenRgAcl(acc.ACL), + + "company": acc.Company, + "companyurl": acc.CompanyURL, + "created_by": acc.CreatedBy, + + "created_time": acc.CreatedTime, + + "deactivation_time": acc.DeactivationTime, + "deleted_by": acc.DeletedBy, + + "deleted_time": acc.DeletedTime, + + "displayname": acc.DisplayName, + "guid": acc.GUID, + + "account_id": acc.ID, + "account_name": acc.Name, + + "resource_limits": flattenRgResourceLimits(acc.ResourceLimits), + "send_access_emails": acc.SendAccessEmails, + // "service_account": acc.ServiceAccount, + + "status": acc.Status, + "updated_time": acc.UpdatedTime, + + "version": acc.Version, + "vins": acc.VINS, + } + res = append(res, temp) + } + return res +} + +func flattenAccountAuditsList(aal account.ListAudits) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, aa := range aal { + temp := map[string]interface{}{ + "call": aa.Call, + "responsetime": aa.ResponseTime, + "statuscode": aa.StatusCode, + "timestamp": aa.Timestamp, + "user": aa.User, + } + res = append(res, temp) + } + return res +} + +func flattenAccountComputesList(acl account.ListComputes) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, acc := range acl { + temp := map[string]interface{}{ + "account_id": acc.AccountID, + "account_name": acc.AccountName, + "cpus": acc.CPUs, + "created_by": acc.CreatedBy, + "created_time": acc.CreatedTime, + "deleted_by": acc.DeletedBy, + "deleted_time": acc.DeletedTime, + "compute_id": acc.ID, + "compute_name": acc.Name, + "ram": acc.RAM, + "registered": acc.Registered, + "rg_id": acc.RGID, + "rg_name": acc.RgName, + "status": acc.Status, + "tech_status": acc.TechStatus, + "total_disks_size": acc.TotalDisksSize, + "updated_by": acc.UpdatedBy, + "updated_time": acc.UpdatedTime, + "user_managed": acc.UserManaged, + "vins_connected": acc.VINSConnected, + } + res = append(res, temp) + } + return res +} + +func flattenAccountDisksList(adl account.ListDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, ad := range adl { + temp := map[string]interface{}{ + "disk_id": ad.ID, + "disk_name": ad.Name, + "pool_name": ad.Pool, + "sep_id": ad.SepID, + "size_max": ad.SizeMax, + "type": ad.Type, + } + res = append(res, temp) + } + return res +} + +func flattenAccountFlipGroupsList(afgl account.ListFLIPGroups) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, afg := range afgl { + temp := map[string]interface{}{ + "account_id": afg.AccountID, + "client_type": afg.ClientType, + "conn_type": afg.ConnType, + "created_by": afg.CreatedBy, + "created_time": afg.CreatedTime, + "default_gw": afg.DefaultGW, + "deleted_by": afg.DeletedBy, + "deleted_time": afg.DeletedTime, + "desc": afg.Description, + "gid": afg.GID, + "guid": afg.GUID, + "fg_id": afg.ID, + "ip": afg.IP, + "milestones": afg.Milestones, + "fg_name": afg.Name, + "net_id": afg.NetID, + "net_type": afg.NetType, + "netmask": afg.Netmask, + "status": afg.Status, + "updated_by": afg.UpdatedBy, + "updated_time": afg.UpdatedTime, + } + res = append(res, temp) + } + return res +} + +func flattenAccountVinsList(avl account.ListVINS) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, av := range avl { + temp := map[string]interface{}{ + "account_id": av.AccountID, + "account_name": av.AccountName, + "computes": av.Computes, + "created_by": av.CreatedBy, + "created_time": av.CreatedTime, + "deleted_by": av.DeletedBy, + "deleted_time": av.DeletedTime, + "external_ip": av.ExternalIP, + "vin_id": av.ID, + "vin_name": av.Name, + "network": av.Network, + "pri_vnf_dev_id": av.PriVNFDevID, + "rg_id": av.RGID, + "rg_name": av.RGName, + "status": av.Status, + "updated_by": av.UpdatedBy, + "updated_time": av.UpdatedTime, + } + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/account/resource_account.go b/internal/service/cloudbroker/account/resource_account.go index 9d4ddfb..6e218df 100644 --- a/internal/service/cloudbroker/account/resource_account.go +++ b/internal/service/cloudbroker/account/resource_account.go @@ -33,95 +33,94 @@ package account import ( "context" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" - log "github.com/sirupsen/logrus" ) func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceAccountCreate") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := account.CreateRequest{} - urlValues.Add("name", d.Get("account_name").(string)) - urlValues.Add("username", d.Get("username").(string)) + req.Name = d.Get("account_name").(string) + req.Username = d.Get("username").(string) if emailaddress, ok := d.GetOk("emailaddress"); ok { - urlValues.Add("emailaddress", emailaddress.(string)) + req.EmailAddress = emailaddress.(string) } if sendAccessEmails, ok := d.GetOk("send_access_emails"); ok { - urlValues.Add("sendAccessEmails", strconv.FormatBool(sendAccessEmails.(bool))) + req.SendAccessEmails = sendAccessEmails.(bool) } if resLimits, ok := d.GetOk("resource_limits"); ok { resLimit := resLimits.([]interface{})[0] resLimitConv := resLimit.(map[string]interface{}) if resLimitConv["cu_m"] != nil { - maxMemCap := int(resLimitConv["cu_m"].(float64)) + maxMemCap := int64(resLimitConv["cu_m"].(float64)) if maxMemCap == 0 { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1)) + req.MaxMemoryCapacity = -1 } else { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap)) + req.MaxMemoryCapacity = maxMemCap } } if resLimitConv["cu_d"] != nil { - maxDiskCap := int(resLimitConv["cu_d"].(float64)) + maxDiskCap := int64(resLimitConv["cu_d"].(float64)) if maxDiskCap == 0 { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1)) + req.MaxVDiskCapacity = -1 } else { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap)) + req.MaxVDiskCapacity = maxDiskCap } } if resLimitConv["cu_c"] != nil { - maxCPUCap := int(resLimitConv["cu_c"].(float64)) + maxCPUCap := int64(resLimitConv["cu_c"].(float64)) if maxCPUCap == 0 { - urlValues.Add("maxCPUCapacity", strconv.Itoa(-1)) + req.MaxCPUCapacity = -1 } else { - urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap)) + req.MaxCPUCapacity = maxCPUCap } } if resLimitConv["cu_i"] != nil { - maxNumPublicIP := int(resLimitConv["cu_i"].(float64)) + maxNumPublicIP := int64(resLimitConv["cu_i"].(float64)) if maxNumPublicIP == 0 { - urlValues.Add("maxNumPublicIP", strconv.Itoa(-1)) + req.MaxNumPublicIP = -1 } else { - urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP)) + req.MaxNumPublicIP = maxNumPublicIP } } if resLimitConv["cu_np"] != nil { - maxNP := int(resLimitConv["cu_np"].(float64)) + maxNP := int64(resLimitConv["cu_np"].(float64)) if maxNP == 0 { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1)) + req.MaxNetworkPeerTransfer = -1 } else { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP)) + req.MaxNetworkPeerTransfer = maxNP } } if resLimitConv["gpu_units"] != nil { - gpuUnits := int(resLimitConv["gpu_units"].(float64)) + gpuUnits := int64(resLimitConv["gpu_units"].(float64)) if gpuUnits == 0 { - urlValues.Add("gpu_units", strconv.Itoa(-1)) + req.GPUUnits = -1 } else { - urlValues.Add("gpu_units", strconv.Itoa(gpuUnits)) + req.GPUUnits = gpuUnits } } } - accountId, err := c.DecortAPICall(ctx, "POST", accountCreateAPI, urlValues) + accountId, err := c.CloudBroker().Account().Create(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(accountId) + d.SetId(strconv.FormatUint(accountId, 10)) d.Set("account_id", accountId) diagnostics := resourceAccountRead(ctx, d, m) @@ -130,19 +129,24 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf } if enable, ok := d.GetOk("enable"); ok { - api := accountDisableAPI enable := enable.(bool) if enable { - api = accountEnableAPI - } - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) + req := account.EnableRequest{ + AccountID: accountId, + } + _, err := c.CloudBroker().Account().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := account.DisableRequest{ + AccountID: accountId, + } + _, err := c.CloudBroker().Account().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } } - - urlValues = &url.Values{} } if users, ok := d.GetOk("users"); ok { @@ -151,15 +155,16 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf if len(addedUsers) > 0 { for _, user := range addedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string))) - _, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues) + req := account.AddUserRequest{ + AccountID: accountId, + Username: userConv["user_id"].(string), + AccessType: userConv["access_type"].(string), + } + + _, err := c.CloudBroker().Account().AddUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } } @@ -171,34 +176,12 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interfac log.Debugf("resourceAccountRead") acc, err := utilityAccountCheckPresence(ctx, d, m) - if acc == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } - d.Set("dc_location", acc.DCLocation) - d.Set("resources", flattenAccResources(acc.Resources)) - d.Set("ckey", acc.CKey) - d.Set("meta", flattens.FlattenMeta(acc.Meta)) - d.Set("acl", flattenAccAcl(acc.Acl)) - d.Set("company", acc.Company) - d.Set("companyurl", acc.CompanyUrl) - d.Set("created_by", acc.CreatedBy) - d.Set("created_time", acc.CreatedTime) - d.Set("deactivation_time", acc.DeactiovationTime) - d.Set("deleted_by", acc.DeletedBy) - d.Set("deleted_time", acc.DeletedTime) - d.Set("displayname", acc.DisplayName) - d.Set("guid", acc.GUID) - d.Set("account_id", acc.ID) - d.Set("account_name", acc.Name) - d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits)) - d.Set("send_access_emails", acc.SendAccessEmails) - d.Set("service_account", acc.ServiceAccount) - d.Set("status", acc.Status) - d.Set("updated_time", acc.UpdatedTime) - d.Set("version", acc.Version) - d.Set("vins", acc.Vins) + flattenResourceAccount(d, acc) return nil } @@ -206,58 +189,65 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interfac func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceAccountDelete") - account, err := utilityAccountCheckPresence(ctx, d, m) - if account == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + accountData, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) + req := account.DeleteRequest{ + AccountID: accountData.ID, + Permanently: d.Get("permanently").(bool), + } - _, err = c.DecortAPICall(ctx, "POST", accountDeleteAPI, urlValues) + _, err = c.CloudBroker().Account().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } -func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceAccountEdit") +func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Debugf("resourceAccountUpdate") c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + acc, err := utilityAccountCheckPresence(ctx, d, m) + if err != nil { + d.SetId("") + return diag.FromErr(err) + } + if d.HasChange("enable") { - api := accountDisableAPI enable := d.Get("enable").(bool) if enable { - api = accountEnableAPI - } - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) + req := account.EnableRequest{ + AccountID: acc.ID, + } + _, err := c.CloudBroker().Account().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } + } else { + req := account.DisableRequest{ + AccountID: acc.ID, + } + _, err := c.CloudBroker().Account().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } } - - urlValues = &url.Values{} } + updateReq := account.UpdateRequest{AccountID: acc.ID} + hasChange := false + if d.HasChange("account_name") { - urlValues.Add("name", d.Get("account_name").(string)) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues) - if err != nil { - return diag.FromErr(err) - } + updateReq.Name = d.Get("account_name").(string) - urlValues = &url.Values{} + hasChange = true } if d.HasChange("resource_limits") { resLimit := d.Get("resource_limits").([]interface{})[0] @@ -266,85 +256,81 @@ func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interfac if resLimitConv["cu_m"] != nil { maxMemCap := int(resLimitConv["cu_m"].(float64)) if maxMemCap == 0 { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1)) + updateReq.MaxMemoryCapacity = -1 } else { - urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap)) + updateReq.MaxMemoryCapacity = int64(maxMemCap) } } if resLimitConv["cu_d"] != nil { maxDiskCap := int(resLimitConv["cu_d"].(float64)) if maxDiskCap == 0 { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1)) + updateReq.MaxVDiskCapacity = -1 } else { - urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap)) + updateReq.MaxVDiskCapacity = int64(maxDiskCap) } } if resLimitConv["cu_c"] != nil { maxCPUCap := int(resLimitConv["cu_c"].(float64)) if maxCPUCap == 0 { - urlValues.Add("maxCPUCapacity", strconv.Itoa(-1)) + updateReq.MaxCPUCapacity = -1 } else { - urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap)) + updateReq.MaxCPUCapacity = int64(maxCPUCap) } } if resLimitConv["cu_i"] != nil { maxNumPublicIP := int(resLimitConv["cu_i"].(float64)) if maxNumPublicIP == 0 { - urlValues.Add("maxNumPublicIP", strconv.Itoa(-1)) + updateReq.MaxNumPublicIP = -1 } else { - urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP)) + updateReq.MaxNumPublicIP = int64(maxNumPublicIP) } } if resLimitConv["cu_np"] != nil { maxNP := int(resLimitConv["cu_np"].(float64)) if maxNP == 0 { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1)) + updateReq.MaxNetworkPeerTransfer = -1 } else { - urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP)) + updateReq.MaxNetworkPeerTransfer = int64(maxNP) } } if resLimitConv["gpu_units"] != nil { gpuUnits := int(resLimitConv["gpu_units"].(float64)) if gpuUnits == 0 { - urlValues.Add("gpu_units", strconv.Itoa(-1)) + updateReq.GPUUnits = -1 } else { - urlValues.Add("gpu_units", strconv.Itoa(gpuUnits)) + updateReq.GPUUnits = int64(gpuUnits) } } - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues) - if err != nil { - return diag.FromErr(err) - } - - urlValues = &url.Values{} + hasChange = true } if d.HasChange("send_access_emails") { - urlValues.Add("sendAccessEmails", strconv.FormatBool(d.Get("send_access_emails").(bool))) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues) + updateReq.SendAccessEmails = d.Get("send_access_emails").(bool) + hasChange = true + } + + if hasChange { + _, err := c.CloudBroker().Account().Update(ctx, updateReq) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("restore") { restore := d.Get("restore").(bool) if restore { - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlValues) + req := account.RestoreRequest{ + AccountID: acc.ID, + } + + _, err := c.CloudBroker().Account().Restore(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } @@ -374,45 +360,48 @@ func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interfac if len(deletedUsers) > 0 { for _, user := range deletedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("recursivedelete", strconv.FormatBool(userConv["recursive_delete"].(bool))) - _, err := c.DecortAPICall(ctx, "POST", accountDeleteUserAPI, urlValues) + req := account.DeleteUserRequest{ + AccountID: acc.ID, + UserName: userConv["user_id"].(string), + RecursiveDelete: userConv["recursive_delete"].(bool), + } + + _, err := c.CloudBroker().Account().DeleteUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(addedUsers) > 0 { for _, user := range addedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string))) - _, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues) + req := account.AddUserRequest{ + AccountID: acc.ID, + Username: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + } + + _, err := c.CloudBroker().Account().AddUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } if len(updatedUsers) > 0 { for _, user := range updatedUsers { userConv := user.(map[string]interface{}) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("userId", userConv["user_id"].(string)) - urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string))) - _, err := c.DecortAPICall(ctx, "POST", accountUpdateUserAPI, urlValues) + req := account.UpdateUserRequest{ + AccountID: acc.ID, + UserID: userConv["user_id"].(string), + AccessType: strings.ToUpper(userConv["access_type"].(string)), + } + + _, err := c.CloudBroker().Account().UpdateUser(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } } @@ -451,7 +440,7 @@ func ResourceAccount() *schema.Resource { CreateContext: resourceAccountCreate, ReadContext: resourceAccountRead, - UpdateContext: resourceAccountEdit, + UpdateContext: resourceAccountUpdate, DeleteContext: resourceAccountDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudbroker/account/utility_account.go b/internal/service/cloudbroker/account/utility_account.go index 0f3569d..7a70f04 100644 --- a/internal/service/cloudbroker/account/utility_account.go +++ b/internal/service/cloudbroker/account/utility_account.go @@ -33,34 +33,28 @@ package account import ( "context" - "encoding/json" - "net/url" "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*AccountWithResources, error) { - account := &AccountWithResources{} +func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.RecordAccount, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := account.GetRequest{} if (strconv.Itoa(d.Get("account_id").(int))) != "0" { - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) + req.AccountID = uint64(d.Get("account_id").(int)) } else { - urlValues.Add("accountId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.AccountID = id } log.Debugf("utilityAccountCheckPresence: load account") - accountRaw, err := c.DecortAPICall(ctx, "POST", accountGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(accountRaw), &account) + account, err := c.CloudBroker().Account().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_audits_list.go b/internal/service/cloudbroker/account/utility_account_audits_list.go index 7c9e8a5..b381430 100644 --- a/internal/service/cloudbroker/account/utility_account_audits_list.go +++ b/internal/service/cloudbroker/account/utility_account_audits_list.go @@ -33,30 +33,22 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountAuditsList, error) { - accountAuditsList := AccountAuditsList{} +func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAudits, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - log.Debugf("utilityAccountAuditsListCheckPresence: load account list") - accountAuditsListRaw, err := c.DecortAPICall(ctx, "POST", accountAuditsAPI, urlValues) - if err != nil { - return nil, err + req := account.AuditsRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(accountAuditsListRaw), &accountAuditsList) + log.Debugf("utilityAccountAuditsListCheckPresence: load account list") + accountAuditsList, err := c.CloudBroker().Account().Audits(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_computes_list.go b/internal/service/cloudbroker/account/utility_account_computes_list.go index 000d723..bcf695a 100644 --- a/internal/service/cloudbroker/account/utility_account_computes_list.go +++ b/internal/service/cloudbroker/account/utility_account_computes_list.go @@ -33,30 +33,22 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountComputesList, error) { - accountComputesList := AccountComputesList{} +func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListComputes, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - log.Debugf("utilityAccountComputesListCheckPresence: load account list") - accountComputesListRaw, err := c.DecortAPICall(ctx, "POST", accountListComputesAPI, urlValues) - if err != nil { - return nil, err + req := account.ListComputesRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(accountComputesListRaw), &accountComputesList) + log.Debugf("utilityAccountComputesListCheckPresence: load account list") + accountComputesList, err := c.CloudBroker().Account().ListComputes(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_deleted_list.go b/internal/service/cloudbroker/account/utility_account_deleted_list.go index 529cc81..78407df 100644 --- a/internal/service/cloudbroker/account/utility_account_deleted_list.go +++ b/internal/service/cloudbroker/account/utility_account_deleted_list.go @@ -33,35 +33,27 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountList, error) { - accountDeletedList := AccountList{} +func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAccounts, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := account.ListDeletedRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityAccountDeletedListCheckPresence: load") - accountDeletedListRaw, err := c.DecortAPICall(ctx, "POST", accountListDeletedAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(accountDeletedListRaw), &accountDeletedList) + accountDeletedList, err := c.CloudBroker().Account().ListDeleted(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_disks_list.go b/internal/service/cloudbroker/account/utility_account_disks_list.go index acf90c2..0028b1a 100644 --- a/internal/service/cloudbroker/account/utility_account_disks_list.go +++ b/internal/service/cloudbroker/account/utility_account_disks_list.go @@ -33,30 +33,22 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountDisksList, error) { - accountDisksList := AccountDisksList{} +func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListDisks, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - log.Debugf("utilityAccountDisksListCheckPresence: load account list") - accountDisksListRaw, err := c.DecortAPICall(ctx, "POST", accountListDisksAPI, urlValues) - if err != nil { - return nil, err + req := account.ListDisksRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(accountDisksListRaw), &accountDisksList) + log.Debugf("utilityAccountDisksListCheckPresence: load account list") + accountDisksList, err := c.CloudBroker().Account().ListDisks(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_flip_groups.go b/internal/service/cloudbroker/account/utility_account_flip_groups.go index 254aa0a..7f14cee 100644 --- a/internal/service/cloudbroker/account/utility_account_flip_groups.go +++ b/internal/service/cloudbroker/account/utility_account_flip_groups.go @@ -33,30 +33,22 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountFlipGroupsList, error) { - accountFlipGroupsList := AccountFlipGroupsList{} +func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListFLIPGroups, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - log.Debugf("utilityAccountFlipGroupsListCheckPresence") - accountFlipGroupsListRaw, err := c.DecortAPICall(ctx, "POST", accountListFlipGroupsAPI, urlValues) - if err != nil { - return nil, err + req := account.ListFLIPGroupsRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(accountFlipGroupsListRaw), &accountFlipGroupsList) + log.Debugf("utilityAccountFlipGroupsListCheckPresence") + accountFlipGroupsList, err := c.CloudBroker().Account().ListFLIPGroups(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_list.go b/internal/service/cloudbroker/account/utility_account_list.go index 8baefc1..f572ea8 100644 --- a/internal/service/cloudbroker/account/utility_account_list.go +++ b/internal/service/cloudbroker/account/utility_account_list.go @@ -33,35 +33,27 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountList, error) { - accountList := AccountList{} +func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAccounts, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := account.ListRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityAccountListCheckPresence: load account list") - accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(accountListRaw), &accountList) + accountList, err := c.CloudBroker().Account().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_rg_list.go b/internal/service/cloudbroker/account/utility_account_rg_list.go index f3822a9..3be8fd7 100644 --- a/internal/service/cloudbroker/account/utility_account_rg_list.go +++ b/internal/service/cloudbroker/account/utility_account_rg_list.go @@ -33,30 +33,22 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountRGList, error) { - accountRGList := AccountRGList{} +func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListRG, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - log.Debugf("utilityAccountRGListCheckPresence: load account list") - accountRGListRaw, err := c.DecortAPICall(ctx, "POST", accountListRGAPI, urlValues) - if err != nil { - return nil, err + req := account.ListRGRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(accountRGListRaw), &accountRGList) + log.Debugf("utilityAccountRGListCheckPresence: load account list") + accountRGList, err := c.CloudBroker().Account().ListRG(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/account/utility_account_vins_list.go b/internal/service/cloudbroker/account/utility_account_vins_list.go index 4c3915e..571b8cd 100644 --- a/internal/service/cloudbroker/account/utility_account_vins_list.go +++ b/internal/service/cloudbroker/account/utility_account_vins_list.go @@ -33,30 +33,22 @@ package account import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountVinsList, error) { - accountVinsList := AccountVinsList{} +func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - - log.Debugf("utilityAccountVinsListCheckPresence: load account list") - accountVinsListRaw, err := c.DecortAPICall(ctx, "POST", accountListVinsAPI, urlValues) - if err != nil { - return nil, err + req := account.ListVINSRequest{ + AccountID: uint64(d.Get("account_id").(int)), } - err = json.Unmarshal([]byte(accountVinsListRaw), &accountVinsList) + log.Debugf("utilityAccountVinsListCheckPresence: load account list") + accountVinsList, err := c.CloudBroker().Account().ListVINS(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/disks/api.go b/internal/service/cloudbroker/disks/api.go deleted file mode 100644 index 37acf8d..0000000 --- a/internal/service/cloudbroker/disks/api.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package disks - -const disksCreateAPI = "/restmachine/cloudbroker/disks/create" -const disksGetAPI = "/restmachine/cloudbroker/disks/get" -const disksListAPI = "/restmachine/cloudbroker/disks/list" -const disksResizeAPI = "/restmachine/cloudbroker/disks/resize2" -const disksRenameAPI = "/restmachine/cloudbroker/disks/rename" -const disksDeleteAPI = "/restmachine/cloudbroker/disks/delete" -const disksIOLimitAPI = "/restmachine/cloudbroker/disks/limitIO" -const disksRestoreAPI = "/restmachine/cloudbroker/disks/restore" diff --git a/internal/service/cloudbroker/disks/data_source_disk.go b/internal/service/cloudbroker/disks/data_source_disk.go index 38419ec..8bf6fdd 100644 --- a/internal/service/cloudbroker/disks/data_source_disk.go +++ b/internal/service/cloudbroker/disks/data_source_disk.go @@ -33,7 +33,6 @@ package disks import ( "context" - "encoding/json" // "net/url" @@ -53,52 +52,7 @@ func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface id := uuid.New() d.SetId(id.String()) - diskAcl, _ := json.Marshal(disk.Acl) - - d.Set("account_id", disk.AccountID) - d.Set("account_name", disk.AccountName) - d.Set("acl", string(diskAcl)) - d.Set("boot_partition", disk.BootPartition) - d.Set("compute_id", disk.ComputeID) - d.Set("compute_name", disk.ComputeName) - d.Set("created_time", disk.CreatedTime) - d.Set("deleted_time", disk.DeletedTime) - d.Set("desc", disk.Desc) - d.Set("destruction_time", disk.DestructionTime) - d.Set("devicename", disk.DeviceName) - d.Set("disk_path", disk.DiskPath) - d.Set("gid", disk.GridID) - d.Set("guid", disk.GUID) - d.Set("disk_id", disk.ID) - d.Set("image_id", disk.ImageID) - d.Set("images", disk.Images) - d.Set("iotune", flattenIOTune(disk.IOTune)) - d.Set("iqn", disk.IQN) - d.Set("login", disk.Login) - d.Set("milestones", disk.Milestones) - d.Set("disk_name", disk.Name) - d.Set("order", disk.Order) - d.Set("params", disk.Params) - d.Set("parent_id", disk.ParentId) - d.Set("passwd", disk.Passwd) - d.Set("pci_slot", disk.PciSlot) - d.Set("pool", disk.Pool) - d.Set("purge_attempts", disk.PurgeAttempts) - d.Set("purge_time", disk.PurgeTime) - d.Set("reality_device_number", disk.RealityDeviceNumber) - d.Set("reference_id", disk.ReferenceId) - d.Set("res_id", disk.ResID) - d.Set("res_name", disk.ResName) - d.Set("role", disk.Role) - d.Set("sep_id", disk.SepID) - d.Set("sep_type", disk.SepType) - d.Set("size_max", disk.SizeMax) - d.Set("size_used", disk.SizeUsed) - d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots)) - d.Set("status", disk.Status) - d.Set("tech_status", disk.TechStatus) - d.Set("type", disk.Type) - d.Set("vmid", disk.VMID) + flattenDisk(d, disk) return nil } @@ -125,14 +79,6 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, - "compute_id": { - Type: schema.TypeInt, - Computed: true, - }, - "compute_name": { - Type: schema.TypeString, - Computed: true, - }, "created_time": { Type: schema.TypeInt, Computed: true, diff --git a/internal/service/cloudbroker/disks/data_source_disk_list.go b/internal/service/cloudbroker/disks/data_source_disk_list.go index f40a0da..5abcc6e 100644 --- a/internal/service/cloudbroker/disks/data_source_disk_list.go +++ b/internal/service/cloudbroker/disks/data_source_disk_list.go @@ -33,7 +33,6 @@ package disks import ( "context" - "encoding/json" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -41,104 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenIOTune(iot IOTune) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - temp := map[string]interface{}{ - "read_bytes_sec": iot.ReadBytesSec, - "read_bytes_sec_max": iot.ReadBytesSecMax, - "read_iops_sec": iot.ReadIopsSec, - "read_iops_sec_max": iot.ReadIopsSecMax, - "size_iops_sec": iot.SizeIopsSec, - "total_bytes_sec": iot.TotalBytesSec, - "total_bytes_sec_max": iot.TotalBytesSecMax, - "total_iops_sec": iot.TotalIopsSec, - "total_iops_sec_max": iot.TotalIopsSecMax, - "write_bytes_sec": iot.WriteBytesSec, - "write_bytes_sec_max": iot.WriteBytesSecMax, - "write_iops_sec": iot.WriteIopsSec, - "write_iops_sec_max": iot.WriteIopsSecMax, - } - - res = append(res, temp) - return res -} - -func flattenDiskList(dl DisksList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, disk := range dl { - diskAcl, _ := json.Marshal(disk.Acl) - temp := map[string]interface{}{ - "account_id": disk.AccountID, - "account_name": disk.AccountName, - "acl": string(diskAcl), - "boot_partition": disk.BootPartition, - "compute_id": disk.ComputeID, - "compute_name": disk.ComputeName, - "created_time": disk.CreatedTime, - "deleted_time": disk.DeletedTime, - "desc": disk.Desc, - "destruction_time": disk.DestructionTime, - "devicename": disk.DeviceName, - "disk_path": disk.DiskPath, - "gid": disk.GridID, - "guid": disk.GUID, - "disk_id": disk.ID, - "image_id": disk.ImageID, - "images": disk.Images, - "iotune": flattenIOTune(disk.IOTune), - "iqn": disk.IQN, - "login": disk.Login, - "machine_id": disk.MachineId, - "machine_name": disk.MachineName, - "milestones": disk.Milestones, - "disk_name": disk.Name, - "order": disk.Order, - "params": disk.Params, - "parent_id": disk.ParentId, - "passwd": disk.Passwd, - "pci_slot": disk.PciSlot, - "pool": disk.Pool, - "purge_attempts": disk.PurgeAttempts, - "purge_time": disk.PurgeTime, - "reality_device_number": disk.RealityDeviceNumber, - "reference_id": disk.ReferenceId, - "res_id": disk.ResID, - "res_name": disk.ResName, - "role": disk.Role, - "sep_id": disk.SepID, - "sep_type": disk.SepType, - "size_max": disk.SizeMax, - "size_used": disk.SizeUsed, - "snapshots": flattendDiskSnapshotList(disk.Snapshots), - "status": disk.Status, - "tech_status": disk.TechStatus, - "type": disk.Type, - "vmid": disk.VMID, - } - res = append(res, temp) - } - return res - -} - -func flattendDiskSnapshotList(sl SnapshotList) []interface{} { - res := make([]interface{}, 0) - for _, snapshot := range sl { - temp := map[string]interface{}{ - "guid": snapshot.Guid, - "label": snapshot.Label, - "res_id": snapshot.ResId, - "snap_set_guid": snapshot.SnapSetGuid, - "snap_set_time": snapshot.SnapSetTime, - "timestamp": snapshot.TimeStamp, - } - res = append(res, temp) - } - - return res - -} - func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { diskList, err := utilityDiskListCheckPresence(ctx, d, m) if err != nil { @@ -195,14 +96,6 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, - "compute_id": { - Type: schema.TypeInt, - Computed: true, - }, - "compute_name": { - Type: schema.TypeString, - Computed: true, - }, "created_time": { Type: schema.TypeInt, Computed: true, diff --git a/internal/service/cloudbroker/disks/flattens.go b/internal/service/cloudbroker/disks/flattens.go new file mode 100644 index 0000000..ec304cf --- /dev/null +++ b/internal/service/cloudbroker/disks/flattens.go @@ -0,0 +1,153 @@ +package disks + +import ( + "encoding/json" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" +) + +func flattenDisk(d *schema.ResourceData, disk *disks.RecordDisk) { + diskAcl, _ := json.Marshal(disk.ACL) + + d.Set("account_id", disk.AccountID) + d.Set("account_name", disk.AccountName) + d.Set("acl", string(diskAcl)) + d.Set("boot_partition", disk.BootPartition) + d.Set("created_time", disk.CreatedTime) + d.Set("deleted_time", disk.DeletedTime) + d.Set("desc", disk.Description) + d.Set("destruction_time", disk.DestructionTime) + d.Set("devicename", disk.DeviceName) + d.Set("disk_path", disk.DiskPath) + d.Set("gid", disk.GID) + d.Set("guid", disk.GUID) + d.Set("disk_id", disk.ID) + d.Set("image_id", disk.ImageID) + d.Set("images", disk.Images) + d.Set("iotune", flattenIOTune(disk.IOTune)) + d.Set("iqn", disk.IQN) + d.Set("login", disk.Login) + d.Set("milestones", disk.Milestones) + d.Set("disk_name", disk.Name) + d.Set("order", disk.Order) + d.Set("params", disk.Params) + d.Set("parent_id", disk.ParentID) + d.Set("passwd", disk.Password) + d.Set("pci_slot", disk.PCISlot) + d.Set("pool", disk.Pool) + d.Set("purge_attempts", disk.PurgeAttempts) + d.Set("purge_time", disk.PurgeTime) + d.Set("reality_device_number", disk.RealityDeviceNumber) + d.Set("reference_id", disk.ReferenceID) + d.Set("res_id", disk.ResID) + d.Set("res_name", disk.ResName) + d.Set("role", disk.Role) + d.Set("sep_id", disk.SEPID) + d.Set("sep_type", disk.SEPType) + d.Set("size_max", disk.SizeMax) + d.Set("size_used", disk.SizeUsed) + d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots)) + d.Set("status", disk.Status) + d.Set("tech_status", disk.TechStatus) + d.Set("type", disk.Type) + d.Set("vmid", disk.VMID) +} + +func flattenIOTune(iot disks.IOTune) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + temp := map[string]interface{}{ + "read_bytes_sec": iot.ReadBytesSec, + "read_bytes_sec_max": iot.ReadBytesSecMax, + "read_iops_sec": iot.ReadIOPSSec, + "read_iops_sec_max": iot.ReadIOPSSecMax, + "size_iops_sec": iot.SizeIOPSSec, + "total_bytes_sec": iot.TotalBytesSec, + "total_bytes_sec_max": iot.TotalBytesSecMax, + "total_iops_sec": iot.TotalIOPSSec, + "total_iops_sec_max": iot.TotalIOPSSecMax, + "write_bytes_sec": iot.WriteBytesSec, + "write_bytes_sec_max": iot.WriteBytesSecMax, + "write_iops_sec": iot.WriteIOPSSec, + "write_iops_sec_max": iot.WriteIOPSSecMax, + } + + res = append(res, temp) + return res +} + +func flattenDiskList(dl disks.ListDisks) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, disk := range dl { + diskAcl, _ := json.Marshal(disk.ACL) + temp := map[string]interface{}{ + "account_id": disk.AccountID, + "account_name": disk.AccountName, + "acl": string(diskAcl), + "boot_partition": disk.BootPartition, + // "compute_id": disk.MachineID, + // "compute_name": disk.MachineName, + "created_time": disk.CreatedTime, + "deleted_time": disk.DeletedTime, + "desc": disk.Description, + "destruction_time": disk.DestructionTime, + "devicename": disk.DeviceName, + "disk_path": disk.DiskPath, + "gid": disk.GID, + "guid": disk.GUID, + "disk_id": disk.ID, + "image_id": disk.ImageID, + "images": disk.Images, + "iotune": flattenIOTune(disk.IOTune), + "iqn": disk.IQN, + "login": disk.Login, + "machine_id": disk.MachineID, + "machine_name": disk.MachineName, + "milestones": disk.Milestones, + "disk_name": disk.Name, + "order": disk.Order, + "params": disk.Params, + "parent_id": disk.ParentID, + "passwd": disk.Password, + "pci_slot": disk.PCISlot, + "pool": disk.Pool, + "purge_attempts": disk.PurgeAttempts, + "purge_time": disk.PurgeTime, + "reality_device_number": disk.RealityDeviceNumber, + "reference_id": disk.ReferenceID, + "res_id": disk.ResID, + "res_name": disk.ResName, + "role": disk.Role, + "sep_id": disk.SEPID, + "sep_type": disk.SEPType, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "snapshots": flattendDiskSnapshotList(disk.Snapshots), + "status": disk.Status, + "tech_status": disk.TechStatus, + "type": disk.Type, + "vmid": disk.VMID, + } + res = append(res, temp) + } + return res + +} + +func flattendDiskSnapshotList(sl disks.ListSnapshots) []interface{} { + res := make([]interface{}, 0) + for _, snapshot := range sl { + temp := map[string]interface{}{ + "guid": snapshot.GUID, + "label": snapshot.Label, + "res_id": snapshot.ResID, + "snap_set_guid": snapshot.SnapSetGUID, + "snap_set_time": snapshot.SnapSetTime, + "timestamp": snapshot.Timestamp, + } + res = append(res, temp) + } + + return res + +} diff --git a/internal/service/cloudbroker/disks/models.go b/internal/service/cloudbroker/disks/models.go deleted file mode 100644 index 84e0cec..0000000 --- a/internal/service/cloudbroker/disks/models.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package disks - -type Disk struct { - Acl map[string]interface{} `json:"acl"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - BootPartition int `json:"bootPartition"` - CreatedTime uint64 `json:"creationTime"` - ComputeID int `json:"computeId"` - ComputeName string `json:"computeName"` - DeletedTime uint64 `json:"deletionTime"` - DeviceName string `json:"devicename"` - Desc string `json:"desc"` - DestructionTime uint64 `json:"destructionTime"` - DiskPath string `json:"diskPath"` - GridID int `json:"gid"` - GUID int `json:"guid"` - ID uint `json:"id"` - ImageID int `json:"imageId"` - Images []int `json:"images"` - IOTune IOTune `json:"iotune"` - IQN string `json:"iqn"` - Login string `json:"login"` - Name string `json:"name"` - MachineId int `json:"machineId"` - MachineName string `json:"machineName"` - Milestones uint64 `json:"milestones"` - Order int `json:"order"` - Params string `json:"params"` - Passwd string `json:"passwd"` - ParentId int `json:"parentId"` - PciSlot int `json:"pciSlot"` - Pool string `json:"pool"` - PurgeTime uint64 `json:"purgeTime"` - PurgeAttempts uint64 `json:"purgeAttempts"` - RealityDeviceNumber int `json:"realityDeviceNumber"` - ReferenceId string `json:"referenceId"` - ResID string `json:"resId"` - ResName string `json:"resName"` - Role string `json:"role"` - SepType string `json:"sepType"` - SepID int `json:"sepId"` // NOTE: absent from compute/get output - SizeMax int `json:"sizeMax"` - SizeUsed float64 `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space - Snapshots []Snapshot `json:"snapshots"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` - UpdateBy uint64 `json:"updateBy"` - VMID int `json:"vmid"` -} - -type Snapshot struct { - Guid string `json:"guid"` - Label string `json:"label"` - ResId string `json:"resId"` - SnapSetGuid string `json:"snapSetGuid"` - SnapSetTime uint64 `json:"snapSetTime"` - TimeStamp uint64 `json:"timestamp"` -} - -type SnapshotList []Snapshot - -type DisksList []Disk - -type IOTune struct { - ReadBytesSec int `json:"read_bytes_sec"` - ReadBytesSecMax int `json:"read_bytes_sec_max"` - ReadIopsSec int `json:"read_iops_sec"` - ReadIopsSecMax int `json:"read_iops_sec_max"` - SizeIopsSec int `json:"size_iops_sec"` - TotalBytesSec int `json:"total_bytes_sec"` - TotalBytesSecMax int `json:"total_bytes_sec_max"` - TotalIopsSec int `json:"total_iops_sec"` - TotalIopsSecMax int `json:"total_iops_sec_max"` - WriteBytesSec int `json:"write_bytes_sec"` - WriteBytesSecMax int `json:"write_bytes_sec_max"` - WriteIopsSec int `json:"write_iops_sec"` - WriteIopsSecMax int `json:"write_iops_sec_max"` -} diff --git a/internal/service/cloudbroker/disks/resource_disk.go b/internal/service/cloudbroker/disks/resource_disk.go index 418ce5a..0c1027e 100644 --- a/internal/service/cloudbroker/disks/resource_disk.go +++ b/internal/service/cloudbroker/disks/resource_disk.go @@ -33,15 +33,14 @@ package disks import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" "strings" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -50,230 +49,178 @@ import ( func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := disks.CreateRequest{} + + req.AccountID = uint64(d.Get("account_id").(int)) + req.GID = uint64(d.Get("gid").(int)) + req.Name = d.Get("disk_name").(string) + req.Size = uint64(d.Get("size_max").(int)) - urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int))) - urlValues.Add("gid", fmt.Sprintf("%d", d.Get("gid").(int))) - urlValues.Add("name", d.Get("disk_name").(string)) - urlValues.Add("size", fmt.Sprintf("%d", d.Get("size_max").(int))) if typeRaw, ok := d.GetOk("type"); ok { - urlValues.Add("type", strings.ToUpper(typeRaw.(string))) + req.Type = strings.ToUpper(typeRaw.(string)) } else { - urlValues.Add("type", "D") + req.Type = "D" } if sepId, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sep_id", strconv.Itoa(sepId.(int))) + req.SEPID = uint64(sepId.(int)) } if poolName, ok := d.GetOk("pool"); ok { - urlValues.Add("pool", poolName.(string)) + req.Pool = poolName.(string) } argVal, argSet := d.GetOk("desc") if argSet { - urlValues.Add("description", argVal.(string)) + req.Description = argVal.(string) } - diskId, err := c.DecortAPICall(ctx, "POST", disksCreateAPI, urlValues) + diskId, err := c.CloudBroker().Disks().Create(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} - - d.SetId(diskId) // update ID of the resource to tell Terraform that the disk resource exists + d.SetId(strconv.FormatUint(diskId, 10)) if iotuneRaw, ok := d.GetOk("iotune"); ok { iot := iotuneRaw.([]interface{})[0] iotune := iot.(map[string]interface{}) - urlValues.Add("diskId", diskId) - urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int))) - urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int))) - urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int))) - urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int))) - urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int))) - urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int))) - urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int))) - urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int))) - urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int))) - urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int))) - urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int))) - urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int))) - urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int))) - - _, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues) + req := disks.LimitIORequest{ + DiskID: diskId, + IOPS: uint64(iotune["total_iops_sec"].(int)), + TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)), + ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)), + WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)), + TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)), + ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)), + WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)), + TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)), + ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)), + WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)), + TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)), + ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)), + WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)), + } + + _, err := c.CloudBroker().Disks().LimitIO(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} - } - - dgn := resourceDiskRead(ctx, d, m) - if dgn != nil { - return dgn } - return nil + return resourceDiskRead(ctx, d, m) } func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { disk, err := utilityDiskCheckPresence(ctx, d, m) - if disk == nil { + if err != nil { d.SetId("") - if err != nil { - return diag.FromErr(err) - } - return nil + return diag.FromErr(err) } - diskAcl, _ := json.Marshal(disk.Acl) - - d.Set("account_id", disk.AccountID) - d.Set("account_name", disk.AccountName) - d.Set("acl", string(diskAcl)) - d.Set("boot_partition", disk.BootPartition) - d.Set("compute_id", disk.ComputeID) - d.Set("compute_name", disk.ComputeName) - d.Set("created_time", disk.CreatedTime) - d.Set("deleted_time", disk.DeletedTime) - d.Set("desc", disk.Desc) - d.Set("destruction_time", disk.DestructionTime) - d.Set("devicename", disk.DeviceName) - d.Set("disk_path", disk.DiskPath) - d.Set("gid", disk.GridID) - d.Set("guid", disk.GUID) - d.Set("disk_id", disk.ID) - d.Set("image_id", disk.ImageID) - d.Set("images", disk.Images) - d.Set("iotune", flattenIOTune(disk.IOTune)) - d.Set("iqn", disk.IQN) - d.Set("login", disk.Login) - d.Set("milestones", disk.Milestones) - d.Set("disk_name", disk.Name) - d.Set("order", disk.Order) - d.Set("params", disk.Params) - d.Set("parent_id", disk.ParentId) - d.Set("passwd", disk.Passwd) - d.Set("pci_slot", disk.PciSlot) - d.Set("pool", disk.Pool) - d.Set("purge_attempts", disk.PurgeAttempts) - d.Set("purge_time", disk.PurgeTime) - d.Set("reality_device_number", disk.RealityDeviceNumber) - d.Set("reference_id", disk.ReferenceId) - d.Set("res_id", disk.ResID) - d.Set("res_name", disk.ResName) - d.Set("role", disk.Role) - d.Set("sep_id", disk.SepID) - d.Set("sep_type", disk.SepType) - d.Set("size_max", disk.SizeMax) - d.Set("size_used", disk.SizeUsed) - d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots)) - d.Set("status", disk.Status) - d.Set("tech_status", disk.TechStatus) - d.Set("type", disk.Type) - d.Set("vmid", disk.VMID) + flattenDisk(d, disk) return nil } func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + diskID, _ := strconv.ParseUint(d.Id(), 10, 64) if d.HasChange("size_max") { oldSize, newSize := d.GetChange("size_max") if oldSize.(int) < newSize.(int) { log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB", d.Id(), oldSize.(int), newSize.(int)) - urlValues.Add("diskId", d.Id()) - urlValues.Add("size", fmt.Sprintf("%d", newSize.(int))) - _, err := c.DecortAPICall(ctx, "POST", disksResizeAPI, urlValues) + req := disks.ResizeRequest{ + DiskID: diskID, + Size: uint64(newSize.(int)), + } + + _, err := c.CloudBroker().Disks().Resize(ctx, req) if err != nil { return diag.FromErr(err) } + d.Set("size_max", newSize) } else if oldSize.(int) > newSize.(int) { return diag.FromErr(fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id())) } - urlValues = &url.Values{} } if d.HasChange("disk_name") { - urlValues.Add("diskId", d.Id()) - urlValues.Add("name", d.Get("disk_name").(string)) - _, err := c.DecortAPICall(ctx, "POST", disksRenameAPI, urlValues) + req := disks.RenameRequest{ + DiskID: diskID, + Name: d.Get("disk_name").(string), + } + + _, err := c.CloudBroker().Disks().Rename(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("iotune") { iot := d.Get("iotune").([]interface{})[0] iotune := iot.(map[string]interface{}) - urlValues.Add("diskId", d.Id()) - urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int))) - urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int))) - urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int))) - urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int))) - urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int))) - urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int))) - urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int))) - urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int))) - urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int))) - urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int))) - urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int))) - urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int))) - urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int))) - - _, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues) + req := disks.LimitIORequest{ + DiskID: diskID, + IOPS: uint64(iotune["total_iops_sec"].(int)), + TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)), + ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)), + WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)), + TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)), + ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)), + WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)), + TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)), + ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)), + WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)), + TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)), + ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)), + WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)), + SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)), + } + + _, err := c.CloudBroker().Disks().LimitIO(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } if d.HasChange("restore") { if d.Get("restore").(bool) { - urlValues.Add("diskId", d.Id()) - urlValues.Add("reason", d.Get("reason").(string)) + req := disks.RestoreRequest{ + DiskID: diskID, + Reason: d.Get("reason").(string), + } - _, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues) + _, err := c.CloudBroker().Disks().Restore(ctx, req) if err != nil { return diag.FromErr(err) } - - urlValues = &url.Values{} } - } return resourceDiskRead(ctx, d, m) } func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + c := m.(*controller.ControllerCfg) disk, err := utilityDiskCheckPresence(ctx, d, m) - if disk == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } - params := &url.Values{} - params.Add("diskId", d.Id()) - params.Add("detach", strconv.FormatBool(d.Get("detach").(bool))) - params.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) - params.Add("reason", d.Get("reason").(string)) + req := disks.DeleteRequest{ + DiskID: disk.ID, + Detach: d.Get("detach").(bool), + Permanently: d.Get("permanently").(bool), + Reason: d.Get("reason").(string), + } - c := m.(*controller.ControllerCfg) - _, err = c.DecortAPICall(ctx, "POST", disksDeleteAPI, params) + _, err = c.CloudBroker().Disks().Delete(ctx, req) if err != nil { return diag.FromErr(err) } @@ -362,14 +309,6 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { Type: schema.TypeInt, Computed: true, }, - "compute_id": { - Type: schema.TypeInt, - Computed: true, - }, - "compute_name": { - Type: schema.TypeString, - Computed: true, - }, "created_time": { Type: schema.TypeInt, Computed: true, diff --git a/internal/service/cloudbroker/disks/utility_disk.go b/internal/service/cloudbroker/disks/utility_disk.go index 2bce9e1..cbbfb37 100644 --- a/internal/service/cloudbroker/disks/utility_disk.go +++ b/internal/service/cloudbroker/disks/utility_disk.go @@ -33,35 +33,28 @@ package disks import ( "context" - "encoding/json" - "net/url" "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Disk, error) { +func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.RecordDisk, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - disk := &Disk{} + req := disks.GetRequest{} if d.Get("disk_id").(int) == 0 { - urlValues.Add("diskId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.DiskID = id } else { - urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int))) + req.DiskID = uint64(d.Get("disk_id").(int)) } log.Debugf("utilityDiskCheckPresence: load disk") - diskRaw, err := c.DecortAPICall(ctx, "POST", disksGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(diskRaw), disk) + disk, err := c.CloudBroker().Disks().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/disks/utility_disk_list.go b/internal/service/cloudbroker/disks/utility_disk_list.go index fbb4296..c953135 100644 --- a/internal/service/cloudbroker/disks/utility_disk_list.go +++ b/internal/service/cloudbroker/disks/utility_disk_list.go @@ -33,42 +33,34 @@ package disks import ( "context" - "encoding/json" - "net/url" - "strconv" "strings" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (DisksList, error) { - diskList := DisksList{} +func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (disks.ListDisks, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := disks.ListRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } if diskType, ok := d.GetOk("type"); ok { - urlValues.Add("type", strings.ToUpper(diskType.(string))) + req.Type = strings.ToUpper(diskType.(string)) } if accountId, ok := d.GetOk("accountId"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } log.Debugf("utilityDiskListCheckPresence: load disk list") - diskListRaw, err := c.DecortAPICall(ctx, "POST", disksListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(diskListRaw), &diskList) + diskList, err := c.CloudBroker().Disks().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/grid/data_source_grid.go b/internal/service/cloudbroker/grid/data_source_grid.go index d871470..c890d75 100644 --- a/internal/service/cloudbroker/grid/data_source_grid.go +++ b/internal/service/cloudbroker/grid/data_source_grid.go @@ -40,21 +40,12 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenGrid(d *schema.ResourceData, grid *Grid) { - d.Set("name", grid.Name) - d.Set("flag", grid.Flag) - d.Set("gid", grid.Gid) - d.Set("guid", grid.Guid) - d.Set("location_code", grid.LocationCode) - d.Set("id", grid.Id) -} - func dataSourceGridRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { grid, err := utilityGridCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - d.SetId(strconv.Itoa(grid.Id)) + d.SetId(strconv.FormatUint(grid.ID, 10)) flattenGrid(d, grid) return nil diff --git a/internal/service/cloudbroker/grid/data_source_grid_list.go b/internal/service/cloudbroker/grid/data_source_grid_list.go index 5a1b37c..44ab8aa 100644 --- a/internal/service/cloudbroker/grid/data_source_grid_list.go +++ b/internal/service/cloudbroker/grid/data_source_grid_list.go @@ -40,23 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenGridList(gl GridList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, item := range gl { - temp := map[string]interface{}{ - "name": item.Name, - "flag": item.Flag, - "gid": item.Gid, - "guid": item.Guid, - "location_code": item.LocationCode, - "id": item.Id, - } - - res = append(res, temp) - } - return res -} - func dataSourceGridListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { gridList, err := utilityGridListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/grid/flattens.go b/internal/service/cloudbroker/grid/flattens.go new file mode 100644 index 0000000..349c699 --- /dev/null +++ b/internal/service/cloudbroker/grid/flattens.go @@ -0,0 +1,32 @@ +package grid + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" +) + +func flattenGrid(d *schema.ResourceData, grid *grid.RecordGrid) { + d.Set("name", grid.Name) + d.Set("flag", grid.Flag) + d.Set("gid", grid.GID) + d.Set("guid", grid.GUID) + d.Set("location_code", grid.LocationCode) + d.Set("id", grid.ID) +} + +func flattenGridList(gl grid.ListGrids) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range gl { + temp := map[string]interface{}{ + "name": item.Name, + "flag": item.Flag, + "gid": item.GID, + "guid": item.GUID, + "location_code": item.LocationCode, + "id": item.ID, + } + + res = append(res, temp) + } + return res +} diff --git a/internal/service/cloudbroker/grid/models.go b/internal/service/cloudbroker/grid/models.go deleted file mode 100644 index 119df57..0000000 --- a/internal/service/cloudbroker/grid/models.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package grid - -type Grid struct { - Flag string `json:"flag"` - Gid int `json:"gid"` - Guid int `json:"guid"` - Id int `json:"id"` - LocationCode string `json:"locationCode"` - Name string `json:"name"` -} - -type GridList []Grid diff --git a/internal/service/cloudbroker/grid/utility_grid.go b/internal/service/cloudbroker/grid/utility_grid.go index 01109d6..f30a985 100644 --- a/internal/service/cloudbroker/grid/utility_grid.go +++ b/internal/service/cloudbroker/grid/utility_grid.go @@ -33,35 +33,27 @@ package grid import ( "context" - "encoding/json" "errors" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityGridCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Grid, error) { - grid := &Grid{} +func utilityGridCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.RecordGrid, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := grid.GetRequest{} if gridId, ok := d.GetOk("grid_id"); ok { - urlValues.Add("gridId", strconv.Itoa(gridId.(int))) + req.GID = uint64(gridId.(int)) } else { return nil, errors.New("grid_id is required") } log.Debugf("utilityGridCheckPresence: load grid") - gridRaw, err := c.DecortAPICall(ctx, "POST", GridGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(gridRaw), grid) + grid, err := c.CloudBroker().Grid().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/grid/utility_grid_list.go b/internal/service/cloudbroker/grid/utility_grid_list.go index 9654fcd..3f48a88 100644 --- a/internal/service/cloudbroker/grid/utility_grid_list.go +++ b/internal/service/cloudbroker/grid/utility_grid_list.go @@ -33,35 +33,27 @@ package grid import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityGridListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (GridList, error) { - gridList := GridList{} +func utilityGridListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (grid.ListGrids, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := grid.ListRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityGridListCheckPresence: load grid list") - gridListRaw, err := c.DecortAPICall(ctx, "POST", GridListGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(gridListRaw), &gridList) + gridList, err := c.CloudBroker().Grid().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/image/data_source_image.go b/internal/service/cloudbroker/image/data_source_image.go index 7776f07..98d58ea 100644 --- a/internal/service/cloudbroker/image/data_source_image.go +++ b/internal/service/cloudbroker/image/data_source_image.go @@ -38,57 +38,15 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) -func flattenImage(d *schema.ResourceData, image *Image) { - d.Set("name", image.Name) - d.Set("drivers", image.Drivers) - d.Set("url", image.Url) - d.Set("gid", image.Gid) - d.Set("image_id", image.ImageId) - d.Set("boot_type", image.Boottype) - d.Set("image_type", image.Imagetype) - d.Set("bootable", image.Bootable) - d.Set("sep_id", image.SepId) - d.Set("unc_path", image.UNCPath) - d.Set("link_to", image.LinkTo) - d.Set("status", image.Status) - d.Set("tech_status", image.TechStatus) - d.Set("version", image.Version) - d.Set("size", image.Size) - d.Set("enabled", image.Enabled) - d.Set("computeci_id", image.ComputeciId) - d.Set("pool_name", image.PoolName) - d.Set("username", image.Username) - d.Set("username_dl", image.UsernameDL) - d.Set("password", image.Password) - d.Set("password_dl", image.PasswordDL) - d.Set("account_id", image.AccountId) - d.Set("guid", image.Guid) - d.Set("milestones", image.Milestones) - d.Set("provider_name", image.ProviderName) - d.Set("purge_attempts", image.PurgeAttempts) - d.Set("reference_id", image.ReferenceId) - d.Set("res_id", image.ResId) - d.Set("res_name", image.ResName) - d.Set("rescuecd", image.Rescuecd) - d.Set("architecture", image.Architecture) - d.Set("hot_resize", image.Hotresize) - d.Set("history", flattenHistory(image.History)) - d.Set("last_modified", image.LastModified) - d.Set("meta", flattens.FlattenMeta(image.Meta)) - d.Set("desc", image.Desc) - d.Set("shared_with", image.SharedWith) -} - func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { image, err := utilityImageCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - d.SetId(strconv.Itoa(image.Guid)) + d.SetId(strconv.FormatUint(image.ID, 10)) flattenImage(d, image) return nil diff --git a/internal/service/cloudbroker/image/data_source_image_list.go b/internal/service/cloudbroker/image/data_source_image_list.go index 0142f4e..5b8f28c 100644 --- a/internal/service/cloudbroker/image/data_source_image_list.go +++ b/internal/service/cloudbroker/image/data_source_image_list.go @@ -40,54 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenImageList(il ImageList) []map[string]interface{} { - res := make([]map[string]interface{}, 0) - for _, item := range il { - temp := map[string]interface{}{ - "name": item.Name, - "url": item.Url, - "gid": item.Gid, - "guid": item.Guid, - "drivers": item.Drivers, - "image_id": item.ImageId, - "boot_type": item.Boottype, - "bootable": item.Bootable, - "image_type": item.Imagetype, - "status": item.Status, - "tech_status": item.TechStatus, - "version": item.Version, - "username": item.Username, - "username_dl": item.UsernameDL, - "password": item.Password, - "password_dl": item.PasswordDL, - "purge_attempts": item.PurgeAttempts, - "architecture": item.Architecture, - "account_id": item.AccountId, - "computeci_id": item.ComputeciId, - "enabled": item.Enabled, - "reference_id": item.ReferenceId, - "res_id": item.ResId, - "res_name": item.ResName, - "rescuecd": item.Rescuecd, - "provider_name": item.ProviderName, - "milestones": item.Milestones, - "size": item.Size, - "sep_id": item.SepId, - "link_to": item.LinkTo, - "unc_path": item.UNCPath, - "pool_name": item.PoolName, - "hot_resize": item.Hotresize, - "history": flattenHistory(item.History), - "last_modified": item.LastModified, - "meta": flattenMeta(item.Meta), - "desc": item.Desc, - "shared_with": item.SharedWith, - } - res = append(res, temp) - } - return res -} - func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { imageList, err := utilityImageListCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/image/data_source_image_list_stacks.go b/internal/service/cloudbroker/image/data_source_image_list_stacks.go index 2d91218..0e39e01 100644 --- a/internal/service/cloudbroker/image/data_source_image_list_stacks.go +++ b/internal/service/cloudbroker/image/data_source_image_list_stacks.go @@ -40,32 +40,6 @@ import ( "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenImageListStacks(_ *schema.ResourceData, stack ImageListStacks) []map[string]interface{} { - temp := make([]map[string]interface{}, 0) - for _, item := range stack { - t := map[string]interface{}{ - "api_url": item.ApiURL, - "api_key": item.ApiKey, - "app_id": item.AppId, - "desc": item.Desc, - "drivers": item.Drivers, - "error": item.Error, - "guid": item.Guid, - "id": item.Id, - "images": item.Images, - "login": item.Login, - "name": item.Name, - "passwd": item.Passwd, - "reference_id": item.ReferenceId, - "status": item.Status, - "type": item.Type, - } - - temp = append(temp, t) - } - return temp -} - func dataSourceImageListStacksRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { imageListStacks, err := utilityImageListStacksCheckPresence(ctx, d, m) if err != nil { diff --git a/internal/service/cloudbroker/image/flattens.go b/internal/service/cloudbroker/image/flattens.go new file mode 100644 index 0000000..d72f319 --- /dev/null +++ b/internal/service/cloudbroker/image/flattens.go @@ -0,0 +1,157 @@ +package image + +import ( + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" +) + +func flattenImage(d *schema.ResourceData, img *image.RecordImage) { + d.Set("name", img.Name) + d.Set("drivers", img.Drivers) + d.Set("url", img.URL) + d.Set("gid", img.GID) + d.Set("image_id", img.ID) + d.Set("boot_type", img.BootType) + d.Set("image_type", img.Type) + d.Set("bootable", img.Bootable) + d.Set("sep_id", img.SEPID) + d.Set("unc_path", img.UNCPath) + d.Set("link_to", img.LinkTo) + d.Set("status", img.Status) + d.Set("tech_status", img.TechStatus) + d.Set("version", img.Version) + d.Set("size", img.Size) + d.Set("enabled", img.Enabled) + d.Set("computeci_id", img.ComputeCIID) + d.Set("pool_name", img.Pool) + d.Set("username", img.Username) + // d.Set("username_dl", img.UsernameDL) + d.Set("password", img.Password) + // d.Set("password_dl", img.PasswordDL) + d.Set("account_id", img.AccountID) + d.Set("guid", img.GUID) + d.Set("milestones", img.Milestones) + d.Set("provider_name", img.ProviderName) + d.Set("purge_attempts", img.PurgeAttempts) + d.Set("reference_id", img.ReferenceID) + d.Set("res_id", img.ResID) + d.Set("res_name", img.ResName) + d.Set("rescuecd", img.RescueCD) + d.Set("architecture", img.Architecture) + d.Set("hot_resize", img.HotResize) + d.Set("history", flattenHistory(img.History)) + d.Set("last_modified", img.LastModified) + d.Set("meta", flattens.FlattenMeta(img.Meta)) + d.Set("desc", img.Description) + d.Set("shared_with", img.SharedWith) +} + +func flattenMeta(m []interface{}) []string { + output := []string{} + for _, item := range m { + switch d := item.(type) { + case string: + output = append(output, d) + case int: + output = append(output, strconv.Itoa(d)) + case int64: + output = append(output, strconv.FormatInt(d, 10)) + case float64: + output = append(output, strconv.FormatInt(int64(d), 10)) + default: + output = append(output, "") + } + } + return output +} + +func flattenHistory(history []image.History) []map[string]interface{} { + temp := make([]map[string]interface{}, 0) + for _, item := range history { + t := map[string]interface{}{ + "id": item.ID, + "guid": item.GUID, + "timestamp": item.Timestamp, + } + + temp = append(temp, t) + } + return temp +} + +func flattenImageList(il image.ListImages) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range il { + temp := map[string]interface{}{ + "name": item.Name, + "url": item.URL, + "gid": item.GID, + "guid": item.GUID, + "drivers": item.Drivers, + "image_id": item.ID, + "boot_type": item.BootType, + "bootable": item.Bootable, + "image_type": item.Type, + "status": item.Status, + "tech_status": item.TechStatus, + "version": item.Version, + "username": item.Username, + // "username_dl": item.UsernameDL, + "password": item.Password, + // "password_dl": item.PasswordDL, + "purge_attempts": item.PurgeAttempts, + "architecture": item.Architecture, + "account_id": item.AccountID, + "computeci_id": item.ComputeCIID, + "enabled": item.Enabled, + "reference_id": item.ReferenceID, + "res_id": item.ResID, + "res_name": item.ResName, + "rescuecd": item.RescueCD, + "provider_name": item.ProviderName, + "milestones": item.Milestones, + "size": item.Size, + "sep_id": item.SEPID, + "link_to": item.LinkTo, + "unc_path": item.UNCPath, + "pool_name": item.Pool, + "hot_resize": item.HotResize, + "history": flattenHistory(item.History), + "last_modified": item.LastModified, + "meta": flattenMeta(item.Meta), + "desc": item.Description, + "shared_with": item.SharedWith, + } + res = append(res, temp) + } + return res +} + +func flattenImageListStacks(_ *schema.ResourceData, stack image.ListStacks) []map[string]interface{} { + temp := make([]map[string]interface{}, 0) + for _, item := range stack { + t := map[string]interface{}{ + "api_url": item.APIURL, + "api_key": item.APIKey, + "app_id": item.AppID, + "desc": item.Description, + "drivers": item.Drivers, + "error": item.Error, + "guid": item.GUID, + "id": item.ID, + "images": item.Images, + "login": item.Login, + "name": item.Name, + "passwd": item.Password, + "reference_id": item.ReferenceID, + "status": item.Status, + "type": item.Type, + } + + temp = append(temp, t) + } + return temp +} diff --git a/internal/service/cloudbroker/image/models.go b/internal/service/cloudbroker/image/models.go deleted file mode 100644 index 60733f4..0000000 --- a/internal/service/cloudbroker/image/models.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package image - -type History struct { - Guid string `json:"guid"` - Id int `json:"id"` - Timestamp int64 `json:"timestamp"` -} - -type Image struct { - ImageId int `json:"id"` - Name string `json:"name"` - Url string `json:"url"` - Gid int `json:"gid"` - Guid int `json:"guid"` - Boottype string `json:"bootType"` - Imagetype string `json:"type"` - Drivers []string `json:"drivers"` - Hotresize bool `json:"hotResize"` - Bootable bool `json:"bootable"` - Username string `json:"username"` - Password string `json:"password"` - AccountId int `json:"accountId"` - UsernameDL string `json:"usernameDL"` - PasswordDL string `json:"passwordDL"` - SepId int `json:"sepId"` - PoolName string `json:"pool"` - Architecture string `json:"architecture"` - UNCPath string `json:"UNCPath"` - LinkTo int `json:"linkTo"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Size int `json:"size"` - Version string `json:"version"` - Enabled bool `json:"enabled"` - ComputeciId int `json:"computeciId"` - Milestones int `json:"milestones"` - ProviderName string `json:"provider_name"` - PurgeAttempts int `json:"purgeAttempts"` - ReferenceId string `json:"referenceId"` - ResId string `json:"resId"` - ResName string `json:"resName"` - Rescuecd bool `json:"rescuecd"` - Meta []interface{} `json:"_meta"` - History []History `json:"history"` - LastModified int64 `json:"lastModified"` - Desc string `json:"desc"` - SharedWith []int `json:"sharedWith"` -} - -type ImageList []Image - -type ImageStack struct { - ApiURL string `json:"apiUrl"` - ApiKey string `json:"apikey"` - AppId string `json:"appId"` - Desc string `json:"desc"` - Drivers []string `json:"drivers"` - Error int `json:"error"` - Guid int `json:"guid"` - Id int `json:"id"` - Images []int `json:"images"` - Login string `json:"login"` - Name string `json:"name"` - Passwd string `json:"passwd"` - ReferenceId string `json:"referenceId"` - Status string `json:"status"` - Type string `json:"type"` -} - -type ImageListStacks []ImageStack diff --git a/internal/service/cloudbroker/image/resource_cdrom_image.go b/internal/service/cloudbroker/image/resource_cdrom_image.go index 96ff5dc..a78a5ca 100644 --- a/internal/service/cloudbroker/image/resource_cdrom_image.go +++ b/internal/service/cloudbroker/image/resource_cdrom_image.go @@ -33,69 +33,57 @@ package image import ( "context" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceCDROMImageCreate: called for image %s", d.Get("name").(string)) - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("url", d.Get("url").(string)) - urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int))) - - tstr := d.Get("drivers").([]interface{}) - temp := "" - l := len(tstr) - for i, str := range tstr { - s := "\"" + str.(string) + "\"" - if i != (l - 1) { - s += "," - } - temp = temp + s + req := image.CreateCDROMImageRequest{ + Name: d.Get("name").(string), + URL: d.Get("url").(string), + GID: uint64(d.Get("gid").(int)), } - temp = "[" + temp + "]" - urlValues.Add("drivers", temp) - if username, ok := d.GetOk("username"); ok { - urlValues.Add("username", username.(string)) + drivers := []string{} + for _, driver := range d.Get("drivers").([]interface{}) { + drivers = append(drivers, driver.(string)) } - if password, ok := d.GetOk("password"); ok { - urlValues.Add("password", password.(string)) - } - if accountId, ok := d.GetOk("account_id"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + + req.Drivers = drivers + + if username, ok := d.GetOk("username_dl"); ok { + req.UsernameDL = username.(string) } - if usernameDL, ok := d.GetOk("username_dl"); ok { - urlValues.Add("usernameDL", usernameDL.(string)) + if password, ok := d.GetOk("password_dl"); ok { + req.PasswordDl = password.(string) } - if passwordDL, ok := d.GetOk("password_dl"); ok { - urlValues.Add("passwordDL", passwordDL.(string)) + if accountId, ok := d.GetOk("account_id"); ok { + req.AccountID = uint64(accountId.(int)) } if sepId, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sepId", strconv.Itoa(sepId.(int))) + req.SEPID = uint64(sepId.(int)) } if poolName, ok := d.GetOk("pool_name"); ok { - urlValues.Add("pool_name", poolName.(string)) + req.PoolName = poolName.(string) } if architecture, ok := d.GetOk("architecture"); ok { - urlValues.Add("architecture", architecture.(string)) + req.Architecture = architecture.(string) } - imageId, err := c.DecortAPICall(ctx, "POST", imageCreateCDROMAPI, urlValues) + imageId, err := c.CloudBroker().Image().CreateCDROMImage(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(imageId) + d.SetId(strconv.FormatUint(imageId, 10)) d.Set("image_id", imageId) image, err := utilityImageCheckPresence(ctx, d, m) @@ -103,9 +91,7 @@ func resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m int return diag.FromErr(err) } - d.SetId(strconv.Itoa(image.ImageId)) d.Set("bootable", image.Bootable) - //d.Set("image_id", image.ImageId) diagnostics := resourceImageRead(ctx, d, m) if diagnostics != nil { @@ -118,26 +104,25 @@ func resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m int func resourceCDROMImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceCDROMImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) - image, err := utilityImageCheckPresence(ctx, d, m) - if image == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + imageData, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + req := image.DeleteCDROMImageRequest{ + ImageID: imageData.ID, + } if permanently, ok := d.GetOk("permanently"); ok { - urlValues.Add("permanently", strconv.FormatBool(permanently.(bool))) + req.Permanently = permanently.(bool) } - _, err = c.DecortAPICall(ctx, "POST", imageDeleteCDROMAPI, urlValues) + _, err = c.CloudBroker().Image().DeleteCDROMImage(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil @@ -192,18 +177,18 @@ func resourceCDROMImageSchemaMake() map[string]*schema.Schema { Computed: true, Description: "Does this machine supports hot resize", }, - "username": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "Optional username for the image", - }, - "password": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "Optional password for the image", - }, + // "username": { + // Type: schema.TypeString, + // Optional: true, + // Computed: true, + // Description: "Optional username for the image", + // }, + // "password": { + // Type: schema.TypeString, + // Optional: true, + // Computed: true, + // Description: "Optional password for the image", + // }, "account_id": { Type: schema.TypeInt, Optional: true, @@ -377,7 +362,7 @@ func ResourceCDROMImage() *schema.Resource { CreateContext: resourceCDROMImageCreate, ReadContext: resourceImageRead, - UpdateContext: resourceImageEdit, + UpdateContext: resourceImageUpdate, DeleteContext: resourceCDROMImageDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudbroker/image/resource_delete_images.go b/internal/service/cloudbroker/image/resource_delete_images.go index ebca61e..f434d91 100644 --- a/internal/service/cloudbroker/image/resource_delete_images.go +++ b/internal/service/cloudbroker/image/resource_delete_images.go @@ -33,54 +33,17 @@ package image import ( "context" - "net/url" - "strconv" - "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourceCreateListImages(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - id := uuid.New() - d.SetId(id.String()) return nil } func resourceDeleteListImages(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceDeleteListImages: start deleting...") - - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - imageIds := d.Get("image_ids").([]interface{}) - temp := "" - l := len(imageIds) - for i, imageId := range imageIds { - s := strconv.Itoa(imageId.(int)) - if i != (l - 1) { - s += ",\n" - } else { - s += "\n" - } - temp = temp + s - } - temp = "[" + temp + "]" - - urlValues.Add("reason", d.Get("reason").(string)) - urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool))) - urlValues.Add("imageIds", temp) - - _, err := c.DecortAPICall(ctx, "POST", imageDeleteImagesAPI, urlValues) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - return nil } diff --git a/internal/service/cloudbroker/image/resource_image.go b/internal/service/cloudbroker/image/resource_image.go index cc06c28..04011b6 100644 --- a/internal/service/cloudbroker/image/resource_image.go +++ b/internal/service/cloudbroker/image/resource_image.go @@ -33,148 +33,84 @@ package image import ( "context" - "errors" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" - log "github.com/sirupsen/logrus" ) func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("url", d.Get("url").(string)) - urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int))) - urlValues.Add("boottype", d.Get("boot_type").(string)) - urlValues.Add("imagetype", d.Get("image_type").(string)) - - tstr := d.Get("drivers").([]interface{}) - temp := "" - l := len(tstr) - for i, str := range tstr { - s := "\"" + str.(string) + "\"" - if i != (l - 1) { - s += "," - } - temp = temp + s + req := image.CreateRequest{ + Name: d.Get("name").(string), + URL: d.Get("url").(string), + GID: uint64(d.Get("gid").(int)), + BootType: d.Get("boot_type").(string), + ImageType: d.Get("image_type").(string), + } + + drivers := []string{} + for _, driver := range d.Get("drivers").([]interface{}) { + drivers = append(drivers, driver.(string)) } - temp = "[" + temp + "]" - urlValues.Add("drivers", temp) + + req.Drivers = drivers if hotresize, ok := d.GetOk("hot_resize"); ok { - urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool))) + req.HotResize = hotresize.(bool) } if username, ok := d.GetOk("username"); ok { - urlValues.Add("username", username.(string)) + req.Username = username.(string) } if password, ok := d.GetOk("password"); ok { - urlValues.Add("password", password.(string)) + req.Password = password.(string) } if accountId, ok := d.GetOk("account_id"); ok { - urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + req.AccountID = uint64(accountId.(int)) } if usernameDL, ok := d.GetOk("username_dl"); ok { - urlValues.Add("usernameDL", usernameDL.(string)) + req.UsernameDL = usernameDL.(string) } if passwordDL, ok := d.GetOk("password_dl"); ok { - urlValues.Add("passwordDL", passwordDL.(string)) + req.PasswordDL = passwordDL.(string) } if sepId, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sepId", strconv.Itoa(sepId.(int))) + req.SEPID = uint64(sepId.(int)) } if poolName, ok := d.GetOk("pool_name"); ok { - urlValues.Add("poolName", poolName.(string)) + req.PoolName = poolName.(string) } if architecture, ok := d.GetOk("architecture"); ok { - urlValues.Add("architecture", architecture.(string)) + req.Architecture = architecture.(string) } - api := "" - if isSync := d.Get("sync").(bool); !isSync { - api = imageCreateAPI - } else { - api = imageSyncCreateAPI - } - imageId, err := c.DecortAPICall(ctx, "POST", api, urlValues) + imageId, err := c.CloudBroker().Image().CreateImage(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(imageId) + d.SetId(strconv.FormatUint(imageId, 10)) d.Set("image_id", imageId) - image, err := utilityImageCheckPresence(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(strconv.Itoa(image.ImageId)) - d.Set("bootable", image.Bootable) - //d.Set("image_id", image.ImageId) - - diagnostics := resourceImageRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceImageRead(ctx, d, m) } func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceImageRead: called for %s id: %s", d.Get("name").(string), d.Id()) image, err := utilityImageCheckPresence(ctx, d, m) - if image == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } - d.Set("name", image.Name) - d.Set("drivers", image.Drivers) - d.Set("url", image.Url) - d.Set("gid", image.Gid) - d.Set("image_id", image.ImageId) - d.Set("boot_type", image.Boottype) - d.Set("image_type", image.Imagetype) - d.Set("bootable", image.Bootable) - d.Set("sep_id", image.SepId) - d.Set("unc_path", image.UNCPath) - d.Set("link_to", image.LinkTo) - d.Set("status", image.Status) - d.Set("tech_status", image.TechStatus) - d.Set("version", image.Version) - d.Set("size", image.Size) - d.Set("enabled", image.Enabled) - d.Set("computeci_id", image.ComputeciId) - d.Set("pool_name", image.PoolName) - d.Set("username", image.Username) - d.Set("username_dl", image.UsernameDL) - d.Set("password", image.Password) - d.Set("password_dl", image.PasswordDL) - d.Set("account_id", image.AccountId) - d.Set("guid", image.Guid) - d.Set("milestones", image.Milestones) - d.Set("provider_name", image.ProviderName) - d.Set("purge_attempts", image.PurgeAttempts) - d.Set("reference_id", image.ReferenceId) - d.Set("res_id", image.ResId) - d.Set("res_name", image.ResName) - d.Set("rescuecd", image.Rescuecd) - d.Set("architecture", image.Architecture) - d.Set("meta", flattens.FlattenMeta(image.Meta)) - d.Set("hot_resize", image.Hotresize) - d.Set("history", flattenHistory(image.History)) - d.Set("last_modified", image.LastModified) - d.Set("desc", image.Desc) - d.Set("shared_with", image.SharedWith) + flattenImage(d, image) return nil } @@ -182,30 +118,28 @@ func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{ func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) - image, err := utilityImageCheckPresence(ctx, d, m) - if image == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + _, err := utilityImageCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + req := image.DeleteRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + if reason, ok := d.GetOk("reason"); ok { - urlValues.Add("reason", reason.(string)) - } else { - urlValues.Add("reason", "") + req.Reason = reason.(string) } if permanently, ok := d.GetOk("permanently"); ok { - urlValues.Add("permanently", strconv.FormatBool(permanently.(bool))) + req.Permanently = permanently.(bool) } - _, err = c.DecortAPICall(ctx, "POST", imageDeleteAPI, urlValues) + _, err = c.CloudBroker().Image().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil @@ -214,10 +148,12 @@ func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interfac func resourceImageEditName(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceImageEditName: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - urlValues.Add("name", d.Get("name").(string)) - _, err := c.DecortAPICall(ctx, "POST", imageEditNameAPI, urlValues) + req := image.RenameRequest{ + ImageID: uint64(d.Get("image_id").(int)), + Name: d.Get("name").(string), + } + + _, err := c.CloudBroker().Image().Rename(ctx, req) if err != nil { return err } @@ -225,17 +161,15 @@ func resourceImageEditName(ctx context.Context, d *schema.ResourceData, m interf return nil } -func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} if d.HasChange("enabled") { err := resourceImageChangeEnabled(ctx, d, m) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if d.HasChange("name") { @@ -243,7 +177,6 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{ if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if d.HasChange("shared_with") { @@ -251,14 +184,13 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{ if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } + if d.HasChange("computeci_id") { err := resourceImageChangeComputeci(ctx, d, m) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if d.HasChange("enabled_stacks") { @@ -266,7 +198,6 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{ if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if d.HasChange("link_to") { @@ -274,21 +205,21 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{ if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} } if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize") { + req := image.EditRequest{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - urlValues.Add("name", d.Get("name").(string)) + req.ImageID = uint64(d.Get("image_id").(int)) + req.Name = d.Get("name").(string) - urlValues.Add("username", d.Get("username").(string)) - urlValues.Add("password", d.Get("password").(string)) - urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int))) - urlValues.Add("bootable", strconv.FormatBool(d.Get("bootable").(bool))) - urlValues.Add("hotresize", strconv.FormatBool(d.Get("hot_resize").(bool))) + req.Username = d.Get("username").(string) + req.Password = d.Get("password").(string) + req.AccountID = uint64(d.Get("account_id").(int)) + req.Bootable = d.Get("bootable").(bool) + req.HotResize = d.Get("hot_resize").(bool) - _, err := c.DecortAPICall(ctx, "POST", imageEditAPI, urlValues) + _, err := c.CloudBroker().Image().Edit(ctx, req) if err != nil { return diag.FromErr(err) } @@ -298,37 +229,41 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{ } func resourceImageChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error { - var api string - c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + imageId := uint64(d.Get("image_id").(int)) + if d.Get("enabled").(bool) { - api = imageEnableAPI + req := image.EnableRequest{ + ImageID: imageId, + } + + _, err := c.CloudBroker().Image().Enable(ctx, req) + if err != nil { + return err + } } else { - api = imageDisableAPI - } - resp, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return err - } - res, err := strconv.ParseBool(resp) - if err != nil { - return err - } - if !res { - return errors.New("Cannot enable/disable") + req := image.DisableRequest{ + ImageID: imageId, + } + + _, err := c.CloudBroker().Image().Disable(ctx, req) + if err != nil { + return err + } } + return nil } func resourceImageLink(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - urlValues.Add("targetId", strconv.Itoa(d.Get("link_to").(int))) - _, err := c.DecortAPICall(ctx, "POST", imageLinkAPI, urlValues) + req := image.LinkRequest{ + ImageID: uint64(d.Get("image_id").(int)), + TargetID: uint64(d.Get("link_to").(int)), + } + + _, err := c.CloudBroker().Image().Link(ctx, req) if err != nil { return err } @@ -339,23 +274,16 @@ func resourceImageLink(ctx context.Context, d *schema.ResourceData, m interface{ func resourceImageShare(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceImageShare: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - accIds := d.Get("shared_with").([]interface{}) - temp := "" - l := len(accIds) - for i, accId := range accIds { - s := strconv.Itoa(accId.(int)) - if i != (l - 1) { - s += ",\n" - } else { - s += "\n" - } - temp = temp + s + req := image.ShareRequest{ + ImageId: uint64(d.Get("image_id").(int)), } - temp = "[" + temp + "]" - urlValues.Add("accounts", temp) - _, err := c.DecortAPICall(ctx, "POST", imageShareAPI, urlValues) + accIds := []uint64{} + for _, accId := range d.Get("shared_with").([]interface{}) { + accIds = append(accIds, uint64(accId.(int))) + } + req.AccountIDs = accIds + + _, err := c.CloudBroker().Image().Share(ctx, req) if err != nil { return err } @@ -365,23 +293,29 @@ func resourceImageShare(ctx context.Context, d *schema.ResourceData, m interface func resourceImageChangeComputeci(ctx context.Context, d *schema.ResourceData, m interface{}) error { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - computeci := d.Get("computeci_id").(int) - - api := "" + imageId := uint64(d.Get("image_id").(int)) + computeci := uint64(d.Get("computeci_id").(int)) if computeci == 0 { - api = imageComputeciUnsetAPI + req := image.ComputeCIUnsetRequest{ + ImageID: imageId, + } + + _, err := c.CloudBroker().Image().ComputeCIUnset(ctx, req) + if err != nil { + return err + } } else { - urlValues.Add("computeciId", strconv.Itoa(computeci)) - api = imageComputeciSetAPI - } + req := image.ComputeCISetRequest{ + ImageID: imageId, + ComputeCIID: computeci, + } - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return err + _, err := c.CloudBroker().Image().ComputeCISet(ctx, req) + if err != nil { + return err + } } return nil @@ -390,21 +324,17 @@ func resourceImageChangeComputeci(ctx context.Context, d *schema.ResourceData, m func resourceImageUpdateNodes(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceImageUpdateNodes: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - enabledStacks := d.Get("enabled_stacks").([]interface{}) - temp := "" - l := len(enabledStacks) - for i, stackId := range enabledStacks { - s := stackId.(string) - if i != (l - 1) { - s += "," - } - temp = temp + s + req := image.UpdateNodesRequest{ + ImageID: uint64(d.Get("image_id").(int)), + } + enabledStacks := []uint64{} + for _, stack := range d.Get("enabled_stacks").([]interface{}) { + enabledStacks = append(enabledStacks, uint64(stack.(int))) } - temp = "[" + temp + "]" - urlValues.Add("enabledStacks", temp) - _, err := c.DecortAPICall(ctx, "POST", imageUpdateNodesAPI, urlValues) + + req.EnabledStacks = enabledStacks + + _, err := c.CloudBroker().Image().UpdateNodes(ctx, req) if err != nil { return err } @@ -661,7 +591,7 @@ func ResourceImage() *schema.Resource { CreateContext: resourceImageCreate, ReadContext: resourceImageRead, - UpdateContext: resourceImageEdit, + UpdateContext: resourceImageUpdate, DeleteContext: resourceImageDelete, Importer: &schema.ResourceImporter{ @@ -679,36 +609,3 @@ func ResourceImage() *schema.Resource { Schema: resourceImageSchemaMake(), } } - -func flattenMeta(m []interface{}) []string { - output := []string{} - for _, item := range m { - switch d := item.(type) { - case string: - output = append(output, d) - case int: - output = append(output, strconv.Itoa(d)) - case int64: - output = append(output, strconv.FormatInt(d, 10)) - case float64: - output = append(output, strconv.FormatInt(int64(d), 10)) - default: - output = append(output, "") - } - } - return output -} - -func flattenHistory(history []History) []map[string]interface{} { - temp := make([]map[string]interface{}, 0) - for _, item := range history { - t := map[string]interface{}{ - "id": item.Id, - "guid": item.Guid, - "timestamp": item.Timestamp, - } - - temp = append(temp, t) - } - return temp -} diff --git a/internal/service/cloudbroker/image/resource_virtual_image.go b/internal/service/cloudbroker/image/resource_virtual_image.go index d7a43e0..fc965f0 100644 --- a/internal/service/cloudbroker/image/resource_virtual_image.go +++ b/internal/service/cloudbroker/image/resource_virtual_image.go @@ -33,47 +33,34 @@ package image import ( "context" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourceVirtualImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("targetId", strconv.Itoa(d.Get("target_id").(int))) - - imageId, err := c.DecortAPICall(ctx, "POST", imageCreateVirtualAPI, urlValues) - if err != nil { - return diag.FromErr(err) + req := image.CreateVirtualRequest{ + Name: d.Get("name").(string), + TargetID: uint64(d.Get("target_id").(int)), } - d.SetId(imageId) - d.Set("image_id", imageId) - - image, err := utilityImageCheckPresence(ctx, d, m) + imageId, err := c.CloudBroker().Image().CreateVirtual(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(strconv.Itoa(image.ImageId)) - d.Set("bootable", image.Bootable) - //d.Set("image_id", image.ImageId) - - diagnostics := resourceImageRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } + d.SetId(strconv.FormatUint(imageId, 10)) + d.Set("image_id", imageId) - return nil + return resourceImageRead(ctx, d, m) } func resourceVirtualImageSchemaMake() map[string]*schema.Schema { @@ -324,7 +311,7 @@ func ResourceVirtualImage() *schema.Resource { CreateContext: resourceVirtualImageCreate, ReadContext: resourceImageRead, - UpdateContext: resourceImageEdit, + UpdateContext: resourceImageUpdate, DeleteContext: resourceImageDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudbroker/image/utility_image.go b/internal/service/cloudbroker/image/utility_image.go index beca9ae..2a210e5 100644 --- a/internal/service/cloudbroker/image/utility_image.go +++ b/internal/service/cloudbroker/image/utility_image.go @@ -33,39 +33,28 @@ package image import ( "context" - "encoding/json" - "errors" - "fmt" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Image, error) { +func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := image.GetRequest{} if (strconv.Itoa(d.Get("image_id").(int))) != "0" { - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + req.ImageID = uint64(d.Get("image_id").(int)) } else { - urlValues.Add("imageId", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.ImageID = id } - resp, err := c.DecortAPICall(ctx, "POST", imageGetAPI, urlValues) + image, err := c.CloudBroker().Image().Get(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - - image := &Image{} - if err := json.Unmarshal([]byte(resp), image); err != nil { - return nil, errors.New(fmt.Sprint("Can not unmarshall data to image: ", resp, " ", image)) - } - return image, nil } diff --git a/internal/service/cloudbroker/image/utility_image_list.go b/internal/service/cloudbroker/image/utility_image_list.go index 49407eb..e6f4de6 100644 --- a/internal/service/cloudbroker/image/utility_image_list.go +++ b/internal/service/cloudbroker/image/utility_image_list.go @@ -33,42 +33,34 @@ package image import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ImageList, error) { - imageList := ImageList{} +func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (image.ListImages, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := image.ListRequest{} if sepId, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sepId", strconv.Itoa(sepId.(int))) + req.SepID = uint64(sepId.(int)) } if sharedWith, ok := d.GetOk("shared_with"); ok { - urlValues.Add("sharedWith", strconv.Itoa(sharedWith.(int))) + req.SharedWith = uint64(sharedWith.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityImageListCheckPresence: load image list") - imageListRaw, err := c.DecortAPICall(ctx, "POST", imageListGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(imageListRaw), &imageList) + imageList, err := c.CloudBroker().Image().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/image/utility_image_list_stacks.go b/internal/service/cloudbroker/image/utility_image_list_stacks.go index 4dd0e9a..582221a 100644 --- a/internal/service/cloudbroker/image/utility_image_list_stacks.go +++ b/internal/service/cloudbroker/image/utility_image_list_stacks.go @@ -33,30 +33,22 @@ package image import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityImageListStacksCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ImageListStacks, error) { - imageListStacks := ImageListStacks{} +func utilityImageListStacksCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (image.ListStacks, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) - - log.Debugf("utilityImageListStacksCheckPresence: load image list") - imageListRaw, err := c.DecortAPICall(ctx, "POST", imageListStacksApi, urlValues) - if err != nil { - return nil, err + req := image.ListStacksRequest{ + ImageID: uint64(d.Get("image_id").(int)), } - err = json.Unmarshal([]byte(imageListRaw), &imageListStacks) + log.Debugf("utilityImageListStacksCheckPresence: load image list") + imageListStacks, err := c.CloudBroker().Image().ListStacks(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/k8s/node_subresource.go b/internal/service/cloudbroker/k8s/node_subresource.go index 7f88fdf..14b4269 100644 --- a/internal/service/cloudbroker/k8s/node_subresource.go +++ b/internal/service/cloudbroker/k8s/node_subresource.go @@ -31,43 +31,68 @@ Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/w package k8s -import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" +) -func nodeMasterDefault() K8sNodeRecord { - return K8sNodeRecord{ +func nodeMasterDefault() k8s.MasterGroup { + return k8s.MasterGroup{ Num: 1, - Cpu: 2, - Ram: 2048, + CPU: 2, + RAM: 2048, Disk: 0, } } -func nodeWorkerDefault() K8sNodeRecord { - return K8sNodeRecord{ +func nodeWorkerDefault() k8s.RecordK8SGroup { + return k8s.RecordK8SGroup{ Num: 1, - Cpu: 1, - Ram: 1024, + CPU: 1, + RAM: 1024, Disk: 0, } } -func parseNode(nodeList []interface{}) K8sNodeRecord { +func parseWorkerNode(nodeList []interface{}) k8s.RecordK8SGroup { node := nodeList[0].(map[string]interface{}) - return K8sNodeRecord{ - Num: node["num"].(int), - Cpu: node["cpu"].(int), - Ram: node["ram"].(int), - Disk: node["disk"].(int), + return k8s.RecordK8SGroup{ + Num: uint64(node["num"].(int)), + CPU: uint64(node["cpu"].(int)), + RAM: uint64(node["ram"].(int)), + Disk: uint64(node["disk"].(int)), } } -func nodeToResource(node K8sNodeRecord) []interface{} { +func parseMasterNode(nodeList []interface{}) k8s.MasterGroup { + node := nodeList[0].(map[string]interface{}) + + return k8s.MasterGroup{ + Num: uint64(node["num"].(int)), + CPU: uint64(node["cpu"].(int)), + RAM: uint64(node["ram"].(int)), + Disk: uint64(node["disk"].(int)), + } +} + +func workerNodeToResource(node k8s.RecordK8SGroup) []interface{} { + mp := make(map[string]interface{}) + + mp["num"] = node.Num + mp["cpu"] = node.CPU + mp["ram"] = node.RAM + mp["disk"] = node.Disk + + return []interface{}{mp} +} + +func masterNodeToResource(node k8s.MasterGroup) []interface{} { mp := make(map[string]interface{}) mp["num"] = node.Num - mp["cpu"] = node.Cpu - mp["ram"] = node.Ram + mp["cpu"] = node.CPU + mp["ram"] = node.RAM mp["disk"] = node.Disk return []interface{}{mp} diff --git a/internal/service/cloudbroker/k8s/resource_k8s.go b/internal/service/cloudbroker/k8s/resource_k8s.go index f36f71e..efea256 100644 --- a/internal/service/cloudbroker/k8s/resource_k8s.go +++ b/internal/service/cloudbroker/k8s/resource_k8s.go @@ -33,85 +33,84 @@ package k8s import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" - "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceK8sCreate: called with name %s, rg %d", d.Get("name").(string), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - urlValues.Add("k8ciId", strconv.Itoa(d.Get("k8sci_id").(int))) - urlValues.Add("workerGroupName", d.Get("wg_name").(string)) + req := k8s.CreateRequest{} + + req.Name = d.Get("name").(string) + req.RGID = uint64(d.Get("rg_id").(int)) + req.K8CIID = uint64(d.Get("k8sci_id").(int)) + req.WorkerGroupName = d.Get("wg_name").(string) - var masterNode K8sNodeRecord + var masterNode k8s.MasterGroup if masters, ok := d.GetOk("masters"); ok { - masterNode = parseNode(masters.([]interface{})) + masterNode = parseMasterNode(masters.([]interface{})) } else { masterNode = nodeMasterDefault() } - urlValues.Add("masterNum", strconv.Itoa(masterNode.Num)) - urlValues.Add("masterCpu", strconv.Itoa(masterNode.Cpu)) - urlValues.Add("masterRam", strconv.Itoa(masterNode.Ram)) - urlValues.Add("masterDisk", strconv.Itoa(masterNode.Disk)) + req.MasterNum = uint64(masterNode.Num) + req.MasterCPU = uint64(masterNode.CPU) + req.MasterRAM = uint64(masterNode.RAM) + req.MasterDisk = uint64(masterNode.Disk) - var workerNode K8sNodeRecord + var workerNode k8s.RecordK8SGroup if workers, ok := d.GetOk("workers"); ok { - workerNode = parseNode(workers.([]interface{})) + workerNode = parseWorkerNode(workers.([]interface{})) } else { workerNode = nodeWorkerDefault() } - urlValues.Add("workerNum", strconv.Itoa(workerNode.Num)) - urlValues.Add("workerCpu", strconv.Itoa(workerNode.Cpu)) - urlValues.Add("workerRam", strconv.Itoa(workerNode.Ram)) - urlValues.Add("workerDisk", strconv.Itoa(workerNode.Disk)) + req.WorkerNum = uint64(workerNode.Num) + req.WorkerCPU = uint64(workerNode.CPU) + req.WorkerRAM = uint64(workerNode.RAM) + req.WorkerDisk = uint64(workerNode.Disk) - //if withLB, ok := d.GetOk("with_lb"); ok { - //urlValues.Add("withLB", strconv.FormatBool(withLB.(bool))) - //} - urlValues.Add("withLB", strconv.FormatBool(true)) + if withLB, ok := d.GetOk("with_lb"); ok { + req.WithLB = withLB.(bool) + } else { + req.WithLB = true + } if extNet, ok := d.GetOk("extnet_id"); ok { - urlValues.Add("extnetId", strconv.Itoa(extNet.(int))) + req.ExtNetID = uint64(extNet.(int)) } else { - urlValues.Add("extnetId", "0") + req.ExtNetID = 0 } - //if desc, ok := d.GetOk("desc"); ok { - //urlValues.Add("desc", desc.(string)) - //} + if desc, ok := d.GetOk("desc"); ok { + req.Description = desc.(string) + } - resp, err := c.DecortAPICall(ctx, "POST", K8sCreateAPI, urlValues) + resp, err := c.CloudBroker().K8S().Create(ctx, req) if err != nil { return diag.FromErr(err) } - urlValues = &url.Values{} - urlValues.Add("auditId", strings.Trim(resp, `"`)) + tasksReq := tasks.GetRequest{ + AuditID: resp, + } for { - resp, err := c.DecortAPICall(ctx, "POST", AsyncTaskGetAPI, urlValues) + task, err := c.CloudBroker().Tasks().Get(ctx, tasksReq) if err != nil { return diag.FromErr(err) } - task := AsyncTask{} - if err := json.Unmarshal([]byte(resp), &task); err != nil { - return diag.FromErr(err) - } log.Debugf("resourceK8sCreate: instance creating - %s", task.Stage) if task.Completed { @@ -126,78 +125,50 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{ time.Sleep(time.Second * 10) } - k8s, err := utilityK8sCheckPresence(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } - - d.Set("default_wg_id", k8s.Groups.Workers[0].ID) - - urlValues = &url.Values{} - urlValues.Add("lbId", strconv.Itoa(k8s.LbID)) - - resp, err = c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues) - if err != nil { - return diag.FromErr(err) - } - - var lb LbRecord - if err := json.Unmarshal([]byte(resp), &lb); err != nil { - return diag.FromErr(err) - } - d.Set("extnet_id", lb.ExtNetID) - d.Set("lb_ip", lb.PrimaryNode.FrontendIP) - - urlValues = &url.Values{} - urlValues.Add("k8sId", d.Id()) - kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues) - if err != nil { - log.Warnf("could not get kubeconfig: %v", err) - } - d.Set("kubeconfig", kubeconfig) - - return nil + return resourceK8sRead(ctx, d, m) } func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceK8sRead: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) - k8s, err := utilityK8sCheckPresence(ctx, d, m) - if k8s == nil { + k8sData, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { d.SetId("") return diag.FromErr(err) } - d.Set("name", k8s.Name) - d.Set("rg_id", k8s.RgID) - d.Set("k8sci_id", k8s.CI) - d.Set("wg_name", k8s.Groups.Workers[0].Name) - d.Set("masters", nodeToResource(k8s.Groups.Masters)) - d.Set("workers", nodeToResource(k8s.Groups.Workers[0])) - d.Set("default_wg_id", k8s.Groups.Workers[0].ID) + d.Set("name", k8sData.Name) + d.Set("rg_id", k8sData.RGID) + d.Set("k8sci_id", k8sData.CIID) + d.Set("wg_name", k8sData.K8SGroups.Workers[0].Name) + d.Set("masters", masterNodeToResource(k8sData.K8SGroups.Masters)) + d.Set("workers", workerNodeToResource(k8sData.K8SGroups.Workers[0])) + d.Set("default_wg_id", k8sData.K8SGroups.Workers[0].ID) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("lbId", strconv.Itoa(k8s.LbID)) - resp, err := c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues) + lbReq := lb.GetRequest{ + LBID: k8sData.LBID, + } + + lbData, err := c.CloudBroker().LB().Get(ctx, lbReq) if err != nil { return diag.FromErr(err) } - var lb LbRecord - if err := json.Unmarshal([]byte(resp), &lb); err != nil { - return diag.FromErr(err) + d.Set("extnet_id", lbData.ExtNetID) + d.Set("lb_ip", lbData.PrimaryNode.FrontendIP) + + configReq := k8s.GetConfigRequest{ + K8SID: k8sData.ID, } - d.Set("extnet_id", lb.ExtNetID) - d.Set("lb_ip", lb.PrimaryNode.FrontendIP) - urlValues = &url.Values{} - urlValues.Add("k8sId", d.Id()) - kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues) + kubeconfig, err := c.CloudBroker().K8S().GetConfig(ctx, configReq) if err != nil { log.Warnf("could not get kubeconfig: %v", err) + return nil } + d.Set("kubeconfig", kubeconfig) return nil @@ -207,40 +178,47 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{ log.Debugf("resourceK8sUpdate: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) + k8sId, _ := strconv.ParseUint(d.Id(), 10, 64) if d.HasChange("name") { - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - urlValues.Add("name", d.Get("name").(string)) + req := k8s.UpdateRequest{ + K8SID: k8sId, + Name: d.Get("name").(string), + } - _, err := c.DecortAPICall(ctx, "POST", K8sUpdateAPI, urlValues) + _, err := c.CloudBroker().K8S().Update(ctx, req) if err != nil { return diag.FromErr(err) } } if d.HasChange("workers") { - k8s, err := utilityK8sCheckPresence(ctx, d, m) + k8sData, err := utilityK8sCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - wg := k8s.Groups.Workers[0] - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - urlValues.Add("workersGroupId", strconv.Itoa(wg.ID)) + wg := k8sData.K8SGroups.Workers[0] + deleteReq := k8s.DeleteWorkerFromGroupRequest{ + K8SID: k8sId, + WorkersGroupID: wg.ID, + } + addReq := k8s.WorkerAddRequest{ + K8SID: k8sId, + WorkersGroupID: wg.ID, + } - newWorkers := parseNode(d.Get("workers").([]interface{})) + newWorkers := parseWorkerNode(d.Get("workers").([]interface{})) if newWorkers.Num > wg.Num { - urlValues.Add("num", strconv.Itoa(newWorkers.Num-wg.Num)) - if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues); err != nil { + addReq.Num = uint64(newWorkers.Num - wg.Num) + if _, err := c.CloudBroker().K8S().WorkerAdd(ctx, addReq); err != nil { return diag.FromErr(err) } } else { for i := wg.Num - 1; i >= newWorkers.Num; i-- { - urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID)) - if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues); err != nil { + deleteReq.WorkerID = wg.DetailedInfo[i].ID + if _, err := c.CloudBroker().K8S().DeleteWorkerFromGroup(ctx, deleteReq); err != nil { return diag.FromErr(err) } } @@ -253,20 +231,22 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{ func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int)) - k8s, err := utilityK8sCheckPresence(ctx, d, m) - if k8s == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + k8sData, err := utilityK8sCheckPresence(ctx, d, m) + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) - urlValues.Add("permanently", "true") + req := k8s.DeleteRequest{ + K8SID: k8sData.ID, + } + if perm, ok := d.GetOk("permanently"); ok { + req.Permanently = perm.(bool) + } else { + req.Permanently = false + } - _, err = c.DecortAPICall(ctx, "POST", K8sDeleteAPI, urlValues) + _, err = c.CloudBroker().K8S().Delete(ctx, req) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudbroker/k8s/resource_k8s_wg.go b/internal/service/cloudbroker/k8s/resource_k8s_wg.go index b8c69fe..83d6db7 100644 --- a/internal/service/cloudbroker/k8s/resource_k8s_wg.go +++ b/internal/service/cloudbroker/k8s/resource_k8s_wg.go @@ -33,12 +33,11 @@ package k8s import ( "context" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) @@ -47,15 +46,16 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("workerNum", strconv.Itoa(d.Get("num").(int))) - urlValues.Add("workerCpu", strconv.Itoa(d.Get("cpu").(int))) - urlValues.Add("workerRam", strconv.Itoa(d.Get("ram").(int))) - urlValues.Add("workerDisk", strconv.Itoa(d.Get("disk").(int))) - - resp, err := c.DecortAPICall(ctx, "POST", K8sWgCreateAPI, urlValues) + req := k8s.WorkersGroupAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + Name: d.Get("name").(string), + WorkerNum: uint64(d.Get("num").(int)), + WorkerCPU: uint64(d.Get("cpu").(int)), + WorkerRAM: uint64(d.Get("ram").(int)), + WorkerDisk: uint64(d.Get("disk").(int)), + } + + resp, err := c.CloudBroker().K8S().WorkersGroupAdd(ctx, req) if err != nil { return diag.FromErr(err) } @@ -69,15 +69,15 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{ log.Debugf("resourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int)) wg, err := utilityK8sWgCheckPresence(ctx, d, m) - if wg == nil { + if err != nil { d.SetId("") return diag.FromErr(err) } d.Set("name", wg.Name) d.Set("num", wg.Num) - d.Set("cpu", wg.Cpu) - d.Set("ram", wg.Ram) + d.Set("cpu", wg.CPU) + d.Set("ram", wg.RAM) d.Set("disk", wg.Disk) return nil @@ -93,20 +93,26 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac return diag.FromErr(err) } - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - urlValues.Add("workersGroupId", d.Id()) + addReq := k8s.WorkerAddRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + } - if newNum := d.Get("num").(int); newNum > wg.Num { - urlValues.Add("num", strconv.Itoa(newNum-wg.Num)) - _, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues) + delReq := k8s.DeleteWorkerFromGroupRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + } + + if newNum := uint64(d.Get("num").(int)); newNum > wg.Num { + addReq.Num = newNum - wg.Num + _, err := c.CloudBroker().K8S().WorkerAdd(ctx, addReq) if err != nil { return diag.FromErr(err) } } else { for i := wg.Num - 1; i >= newNum; i-- { - urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID)) - _, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues) + delReq.WorkerID = wg.DetailedInfo[i].ID + _, err := c.CloudBroker().K8S().DeleteWorkerFromGroup(ctx, delReq) if err != nil { return diag.FromErr(err) } @@ -120,23 +126,23 @@ func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interfac log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int)) wg, err := utilityK8sWgCheckPresence(ctx, d, m) - if wg == nil { - if err != nil { - return diag.FromErr(err) - } - return nil + if err != nil { + return diag.FromErr(err) } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - urlValues.Add("workersGroupId", strconv.Itoa(wg.ID)) + req := k8s.WorkersGroupDeleteRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), + WorkersGroupID: wg.ID, + } - _, err = c.DecortAPICall(ctx, "POST", K8sWgDeleteAPI, urlValues) + _, err = c.CloudBroker().K8S().WorkersGroupDelete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") + return nil } diff --git a/internal/service/cloudbroker/k8s/utility_k8s.go b/internal/service/cloudbroker/k8s/utility_k8s.go index e86d36a..c3ed84a 100644 --- a/internal/service/cloudbroker/k8s/utility_k8s.go +++ b/internal/service/cloudbroker/k8s/utility_k8s.go @@ -33,31 +33,24 @@ package k8s import ( "context" - "encoding/json" - "net/url" + "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8sRecord, error) { +func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8S, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", d.Id()) + req := k8s.GetRequest{} + k8sId, _ := strconv.ParseUint(d.Id(), 10, 64) - resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues) - if err != nil { - return nil, err - } + req.K8SID = k8sId - if resp == "" { - return nil, nil - } - - var k8s K8sRecord - if err := json.Unmarshal([]byte(resp), &k8s); err != nil { + k8s, err := c.CloudBroker().K8S().Get(ctx, req) + if err != nil { return nil, err } - return &k8s, nil + return k8s, nil } diff --git a/internal/service/cloudbroker/k8s/utility_k8s_wg.go b/internal/service/cloudbroker/k8s/utility_k8s_wg.go index 0b1f1f2..0ef6369 100644 --- a/internal/service/cloudbroker/k8s/utility_k8s_wg.go +++ b/internal/service/cloudbroker/k8s/utility_k8s_wg.go @@ -33,40 +33,28 @@ package k8s import ( "context" - "encoding/json" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8sNodeRecord, error) { +func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8SGroup, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) - - resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues) - if err != nil { - return nil, err - } - - if resp == "" { - return nil, nil + req := k8s.GetRequest{ + K8SID: uint64(d.Get("k8s_id").(int)), } - var k8s K8sRecord - if err := json.Unmarshal([]byte(resp), &k8s); err != nil { - return nil, err - } - - id, err := strconv.Atoi(d.Id()) + k8sData, err := c.CloudBroker().K8S().Get(ctx, req) if err != nil { return nil, err } - for _, wg := range k8s.Groups.Workers { - if wg.ID == id { + k8sWgID, _ := strconv.ParseUint(d.Id(), 10, 64) + + for _, wg := range k8sData.K8SGroups.Workers { + if wg.ID == k8sWgID { return &wg, nil } } diff --git a/internal/service/cloudbroker/kvmvm/data_source_compute.go b/internal/service/cloudbroker/kvmvm/data_source_compute.go index 05c77db..030416e 100644 --- a/internal/service/cloudbroker/kvmvm/data_source_compute.go +++ b/internal/service/cloudbroker/kvmvm/data_source_compute.go @@ -33,13 +33,13 @@ package kvmvm import ( "context" - "encoding/json" "fmt" // "net/url" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -48,7 +48,7 @@ import ( // Parse list of all disks from API compute/get into a list of "extra disks" attached to this compute // Extra disks are all compute disks but a boot disk. -func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} { +func parseComputeDisksToExtraDisks(disks compute.ListDisks) []interface{} { // this return value will be used to d.Set("extra_disks",) item of dataSourceCompute schema, // which is a simple list of integer disk IDs excluding boot disk ID length := len(disks) @@ -76,7 +76,7 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} { return result } -func findBootDisk(disks []DiskRecord) *DiskRecord { +func findBootDisk(disks compute.ListDisks) *compute.ItemDisk { for _, d := range disks { if d.Type == "B" { return &d @@ -84,12 +84,12 @@ func findBootDisk(disks []DiskRecord) *DiskRecord { } // some computes don't have a boot disk, so... - return &DiskRecord{} + return &compute.ItemDisk{} } // Parse the list of interfaces from compute/get response into a list of networks // attached to this compute -func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} { +func parseComputeInterfacesToNetworks(ifaces compute.ListInterfaces) []interface{} { // return value will be used to d.Set("network") item of dataSourceCompute schema length := len(ifaces) log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length) @@ -113,68 +113,58 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} { return result } -func flattenCompute(d *schema.ResourceData, compFacts string) error { +func flattenCompute(d *schema.ResourceData, compFacts *compute.RecordCompute) error { // This function expects that compFacts string contains response from API compute/get, // i.e. detailed information about compute instance. // // NOTE: this function modifies ResourceData argument - as such it should never be called // from resourceComputeExists(...) method - model := ComputeGetResp{} - log.Debugf("flattenCompute: ready to unmarshal string %s", compFacts) - err := json.Unmarshal([]byte(compFacts), &model) - if err != nil { - return err - } - log.Debugf("flattenCompute: ID %d, RG ID %d", model.ID, model.RgID) - - d.SetId(fmt.Sprintf("%d", model.ID)) - // d.Set("compute_id", model.ID) - we should NOT set compute_id in the schema here: if it was set - it is already set, if it wasn't - we shouldn't - d.Set("name", model.Name) - d.Set("rg_id", model.RgID) - d.Set("rg_name", model.RgName) - d.Set("account_id", model.AccountID) - d.Set("account_name", model.AccountName) - d.Set("driver", model.Driver) - d.Set("cpu", model.Cpu) - d.Set("ram", model.Ram) - // d.Set("boot_disk_size", model.BootDiskSize) - bootdiskSize key in API compute/get is always zero, so we set boot_disk_size in another way - d.Set("image_id", model.ImageID) - d.Set("description", model.Desc) - d.Set("cloud_init", "applied") // NOTE: for existing compute we hard-code this value as an indicator for DiffSuppress fucntion - // d.Set("status", model.Status) - // d.Set("tech_status", model.TechStatus) - - if model.TechStatus == "STARTED" { + log.Debugf("flattenCompute: ID %d, RG ID %d", compFacts.ID, compFacts.RGID) + + d.SetId(fmt.Sprintf("%d", compFacts.ID)) + d.Set("name", compFacts.Name) + d.Set("rg_id", compFacts.RGID) + d.Set("rg_name", compFacts.RGName) + d.Set("account_id", compFacts.AccountID) + d.Set("account_name", compFacts.AccountName) + d.Set("driver", compFacts.Driver) + d.Set("cpu", compFacts.CPUs) + d.Set("ram", compFacts.RAM) + d.Set("image_id", compFacts.ImageID) + d.Set("description", compFacts.Description) + d.Set("cloud_init", "applied") + + if compFacts.TechStatus == "STARTED" { d.Set("started", true) } else { d.Set("started", false) } - bootDisk := findBootDisk(model.Disks) + bootDisk := findBootDisk(compFacts.Disks) d.Set("boot_disk_size", bootDisk.SizeMax) d.Set("boot_disk_id", bootDisk.ID) // we may need boot disk ID in resize operations - d.Set("sep_id", bootDisk.SepID) + d.Set("sep_id", bootDisk.SEPID) d.Set("pool", bootDisk.Pool) - if len(model.Disks) > 0 { - log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks)) - if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil { + if len(compFacts.Disks) > 0 { + log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(compFacts.Disks)) + if err := d.Set("extra_disks", parseComputeDisksToExtraDisks(compFacts.Disks)); err != nil { return err } } - if len(model.Interfaces) > 0 { - log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(model.Interfaces)) - if err = d.Set("network", parseComputeInterfacesToNetworks(model.Interfaces)); err != nil { + if len(compFacts.Interfaces) > 0 { + log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(compFacts.Interfaces)) + if err := d.Set("network", parseComputeInterfacesToNetworks(compFacts.Interfaces)); err != nil { return err } } - if len(model.OsUsers) > 0 { - log.Debugf("flattenCompute: calling parseOsUsers for %d logins", len(model.OsUsers)) - if err = d.Set("os_users", parseOsUsers(model.OsUsers)); err != nil { + if len(compFacts.OSUsers) > 0 { + log.Debugf("flattenCompute: calling parseOsUsers for %d logins", len(compFacts.OSUsers)) + if err := d.Set("os_users", parseOsUsers(compFacts.OSUsers)); err != nil { return err } } @@ -184,10 +174,8 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error { func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { compFacts, err := utilityComputeCheckPresence(ctx, d, m) - if compFacts == "" { - // if empty string is returned from utilityComputeCheckPresence then there is no - // such Compute and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty + if compFacts == nil { + d.SetId("") return diag.FromErr(err) } @@ -277,7 +265,6 @@ func DataSourceCompute() *schema.Resource { Computed: true, Description: "Name of the OS image this compute instance is based on.", }, - "boot_disk_size": { Type: schema.TypeInt, Computed: true, diff --git a/internal/service/cloudbroker/kvmvm/osusers_subresource.go b/internal/service/cloudbroker/kvmvm/osusers_subresource.go index 99f33ab..258bf37 100644 --- a/internal/service/cloudbroker/kvmvm/osusers_subresource.go +++ b/internal/service/cloudbroker/kvmvm/osusers_subresource.go @@ -33,17 +33,18 @@ package kvmvm import ( log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func parseOsUsers(logins []OsUserRecord) []interface{} { +func parseOsUsers(logins compute.ListOSUsers) []interface{} { var result = make([]interface{}, len(logins)) for index, value := range logins { elem := make(map[string]interface{}) - elem["guid"] = value.Guid + elem["guid"] = value.GUID elem["login"] = value.Login elem["password"] = value.Password elem["public_key"] = value.PubKey diff --git a/internal/service/cloudbroker/kvmvm/resource_compute.go b/internal/service/cloudbroker/kvmvm/resource_compute.go index cb25b95..2b0439f 100644 --- a/internal/service/cloudbroker/kvmvm/resource_compute.go +++ b/internal/service/cloudbroker/kvmvm/resource_compute.go @@ -33,14 +33,16 @@ package kvmvm import ( "context" - "fmt" - "net/url" "strconv" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/kvmppc" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/kvmx86" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs" - log "github.com/sirupsen/logrus" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -49,110 +51,112 @@ import ( func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { if oldVal == "" && newVal != "applied" { - // if old value for "cloud_init" resource is empty string, it means that we are creating new compute - // and there is a chance that the user will want custom cloud init parameters - so we check if - // cloud_init is explicitly set in TF file by making sure that its new value is different from "applied", - // which is a reserved key word. log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) - return false // there is a difference between stored and new value + return false } log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal) - return true // suppress difference + return true } func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - // we assume all mandatory parameters it takes to create a comptue instance are properly - // specified - we rely on schema "Required" attributes to let Terraform validate them for us - log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int)) - // create basic Compute (i.e. without extra disks and network connections - those will be attached - // by subsequent individual API calls). c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int))) - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("cpu", fmt.Sprintf("%d", d.Get("cpu").(int))) - urlValues.Add("ram", fmt.Sprintf("%d", d.Get("ram").(int))) - urlValues.Add("imageId", fmt.Sprintf("%d", d.Get("image_id").(int))) - urlValues.Add("bootDisk", fmt.Sprintf("%d", d.Get("boot_disk_size").(int))) - urlValues.Add("netType", "NONE") // at the 1st step create isolated compute - urlValues.Add("start", "0") // at the 1st step create compute in a stopped state + reqPPC := kvmppc.CreateRequest{} + reqX86 := kvmx86.CreateRequest{} + + reqPPC.RGID = uint64(d.Get("rg_id").(int)) + reqX86.RGID = uint64(d.Get("rg_id").(int)) + + reqPPC.Name = d.Get("name").(string) + reqX86.Name = d.Get("name").(string) + + reqPPC.CPU = uint64(d.Get("cpu").(int)) + reqPPC.RAM = uint64(d.Get("ram").(int)) + reqPPC.ImageID = uint64(d.Get("image_id").(int)) + reqPPC.BootDisk = uint64(d.Get("boot_disk_size").(int)) + reqPPC.NetType = "NONE" + reqPPC.Start = false + + reqX86.CPU = uint64(d.Get("cpu").(int)) + reqX86.RAM = uint64(d.Get("ram").(int)) + reqX86.ImageID = uint64(d.Get("image_id").(int)) + reqX86.BootDisk = uint64(d.Get("boot_disk_size").(int)) + reqX86.NetType = "NONE" + reqX86.Start = false argVal, argSet := d.GetOk("description") if argSet { - urlValues.Add("desc", argVal.(string)) + reqPPC.Description = argVal.(string) + reqX86.Description = argVal.(string) } if sepID, ok := d.GetOk("sep_id"); ok { - urlValues.Add("sepId", strconv.Itoa(sepID.(int))) + reqPPC.SEPID = uint64(sepID.(int)) + reqX86.SEPID = uint64(sepID.(int)) } if pool, ok := d.GetOk("pool"); ok { - urlValues.Add("pool", pool.(string)) + reqPPC.Pool = pool.(string) + reqX86.Pool = pool.(string) } - /* - sshKeysVal, sshKeysSet := d.GetOk("ssh_keys") - if sshKeysSet { - // process SSH Key settings and set API values accordingly - log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)") - urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{}))) + argVal, argSet = d.GetOk("cloud_init") + if argSet { + userdata := argVal.(string) + if userdata != "" && userdata != "applied" { + reqPPC.Userdata = userdata + reqX86.Userdata = userdata } - */ + } - computeCreateAPI := KvmX86CreateAPI + var createdID uint64 driver := d.Get("driver").(string) if driver == "KVM_PPC" { - computeCreateAPI = KvmPPCCreateAPI log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC") - } else { // note that we do not validate arch value for explicit "KVM_X86" here - log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86") - } + id, err := c.CloudBroker().KVMPPC().Create(ctx, reqPPC) + if err != nil { + return diag.FromErr(err) + } - argVal, argSet = d.GetOk("cloud_init") - if argSet { - // userdata must not be empty string and must not be a reserved keyword "applied" - userdata := argVal.(string) - if userdata != "" && userdata != "applied" { - urlValues.Add("userdata", userdata) + createdID = id + } else { + log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86") + id, err := c.CloudBroker().KVMX86().Create(ctx, reqX86) + if err != nil { + return diag.FromErr(err) } - } - apiResp, err := c.DecortAPICall(ctx, "POST", computeCreateAPI, urlValues) - if err != nil { - return diag.FromErr(err) + createdID = id } - // Compute create API returns ID of the new Compute instance on success - d.SetId(apiResp) // update ID of the resource to tell Terraform that the resource exists, albeit partially - compId, _ := strconv.Atoi(apiResp) + d.SetId(strconv.FormatUint(createdID, 10)) cleanup := false defer func() { if cleanup { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("permanently", "1") - urlValues.Add("detachDisks", "1") + req := compute.DeleteRequest{ + ComputeID: createdID, + Permanently: true, + DetachDisks: true, + } - if _, err := c.DecortAPICall(ctx, "POST", ComputeDeleteAPI, urlValues); err != nil { + if _, err := c.CloudBroker().Compute().Delete(ctx, req); err != nil { log.Errorf("resourceComputeCreate: could not delete compute after failed creation: %v", err) } + d.SetId("") } }() - log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string)) + log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", createdID, d.Get("name").(string)) - // Configure data disks if any argVal, argSet = d.GetOk("extra_disks") if argSet && argVal.(*schema.Set).Len() > 0 { - // urlValues.Add("desc", argVal.(string)) log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len()) - err = utilityComputeExtraDisksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute + err := utilityComputeExtraDisksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute if err != nil { - log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", compId, err) + log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", createdID, err) cleanup = true return diag.FromErr(err) } @@ -161,32 +165,28 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf argVal, argSet = d.GetOk("network") if argSet && argVal.(*schema.Set).Len() > 0 { log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len()) - err = utilityComputeNetworksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute + err := utilityComputeNetworksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute if err != nil { - log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err) + log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", createdID, err) cleanup = true return diag.FromErr(err) } } - // Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface), - // now we need to start it before we report the sequence complete if d.Get("started").(bool) { - reqValues := &url.Values{} - reqValues.Add("computeId", fmt.Sprintf("%d", compId)) - log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId) - if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, reqValues); err != nil { + req := compute.StartRequest{ + ComputeID: createdID, + } + + log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", createdID) + if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil { cleanup = true return diag.FromErr(err) } } - log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", compId, d.Get("name").(string)) + log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", createdID, d.Get("name").(string)) - // We may reuse dataSourceComputeRead here as we maintain similarity - // between Compute resource and Compute data source schemas - // Compute read function will also update resource ID on success, so that Terraform - // will know the resource exists return dataSourceComputeRead(ctx, d, m) } @@ -195,11 +195,11 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac d.Get("name").(string), d.Get("rg_id").(int)) compFacts, err := utilityComputeCheckPresence(ctx, d, m) - if compFacts == "" { + if compFacts == nil { if err != nil { return diag.FromErr(err) } - // Compute with such name and RG ID was not found + return nil } @@ -218,6 +218,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf d.Id(), d.Get("name").(string), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) + computeID, _ := strconv.ParseUint(d.Id(), 10, 64) /* 1. Resize CPU/RAM @@ -228,32 +229,34 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf */ // 1. Resize CPU/RAM - params := &url.Values{} + resizeReq := compute.ResizeRequest{ + ComputeID: computeID, + Force: true, + } doUpdate := false - params.Add("computeId", d.Id()) oldCpu, newCpu := d.GetChange("cpu") if oldCpu.(int) != newCpu.(int) { - params.Add("cpu", fmt.Sprintf("%d", newCpu.(int))) + resizeReq.CPU = uint64(newCpu.(int)) doUpdate = true } else { - params.Add("cpu", "0") // no change to CPU allocation + resizeReq.CPU = 0 } oldRam, newRam := d.GetChange("ram") if oldRam.(int) != newRam.(int) { - params.Add("ram", fmt.Sprintf("%d", newRam.(int))) + resizeReq.RAM = uint64(newRam.(int)) doUpdate = true } else { - params.Add("ram", "0") + resizeReq.RAM = 0 } if doUpdate { log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d", oldCpu.(int), newCpu.(int), oldRam.(int), newRam.(int)) - params.Add("force", "true") - _, err := c.DecortAPICall(ctx, "POST", ComputeResizeAPI, params) + + _, err := c.CloudBroker().Compute().Resize(ctx, resizeReq) if err != nil { return diag.FromErr(err) } @@ -262,12 +265,15 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf // 2. Resize (grow) Boot disk oldSize, newSize := d.GetChange("boot_disk_size") if oldSize.(int) < newSize.(int) { - bdsParams := &url.Values{} - bdsParams.Add("diskId", fmt.Sprintf("%d", d.Get("boot_disk_id").(int))) - bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int))) + req := disks.ResizeRequest{ + DiskID: uint64(d.Get("boot_disk_id").(int)), + Size: uint64(newSize.(int)), + } + log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d", d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int)) - _, err := c.DecortAPICall(ctx, "POST", DisksResizeAPI, bdsParams) + + _, err := c.CloudBroker().Disks().Resize(ctx, req) if err != nil { return diag.FromErr(err) } @@ -288,14 +294,18 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf } if d.HasChange("started") { - params := &url.Values{} - params.Add("computeId", d.Id()) if d.Get("started").(bool) { - if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, params); err != nil { + req := compute.StartRequest{ + ComputeID: computeID, + } + if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil { return diag.FromErr(err) } } else { - if _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, params); err != nil { + req := compute.StopRequest{ + ComputeID: computeID, + } + if _, err := c.CloudBroker().Compute().Stop(ctx, req); err != nil { return diag.FromErr(err) } } @@ -307,21 +317,19 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf } func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - // NOTE: this function destroys target Compute instance "permanently", so - // there is no way to restore it. - // If compute being destroyed has some extra disks attached, they are - // detached from the compute log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) + computeID, _ := strconv.ParseUint(d.Id(), 10, 64) - params := &url.Values{} - params.Add("computeId", d.Id()) - params.Add("permanently", "1") - params.Add("detachDisks", "1") + req := compute.DeleteRequest{ + ComputeID: computeID, + Permanently: d.Get("permanently").(bool), + DetachDisks: d.Get("detach_disks").(bool), + } - if _, err := c.DecortAPICall(ctx, "POST", ComputeDeleteAPI, params); err != nil { + if _, err := c.CloudBroker().Compute().Delete(ctx, req); err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudbroker/kvmvm/utility_compute.go b/internal/service/cloudbroker/kvmvm/utility_compute.go index 3a059eb..619b705 100644 --- a/internal/service/cloudbroker/kvmvm/utility_compute.go +++ b/internal/service/cloudbroker/kvmvm/utility_compute.go @@ -33,31 +33,23 @@ package kvmvm import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error { - // d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key - // If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to - // update compute configuration accordingly - // Otherwise it will apply whatever is found in the new set of "extra_disks" right away. - // Primary use of do_delta=false is when calling this function from compute Create handler. - - // Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual - // disks via atomic API calls. However, it will not retry failed manipulation on the same disk. c := m.(*controller.ControllerCfg) + computeID, _ := strconv.ParseUint(d.Id(), 10, 64) log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta) - // NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt old_set, new_set := d.GetChange("extra_disks") apiErrCount := 0 @@ -69,12 +61,13 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa } for _, disk := range new_set.(*schema.Set).List() { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues) + req := compute.DiskAttachRequest{ + ComputeID: computeID, + DiskID: uint64(disk.(int)), + } + + _, err := c.CloudBroker().Compute().DiskAttach(ctx, req) if err != nil { - // failed to attach extra disk - partial resource update apiErrCount++ lastSavedError = err } @@ -92,10 +85,12 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id()) for _, diskId := range detach_set.List() { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskDetachAPI, urlValues) + req := compute.DiskDetachRequest{ + ComputeID: computeID, + DiskID: uint64(diskId.(int)), + } + + _, err := c.CloudBroker().Compute().DiskDetach(ctx, req) if err != nil { // failed to detach disk - there will be partial resource update log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err) @@ -107,10 +102,12 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id()) for _, diskId := range attach_set.List() { - urlValues := &url.Values{} - urlValues.Add("computeId", d.Id()) - urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int))) - _, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues) + req := compute.DiskAttachRequest{ + ComputeID: computeID, + DiskID: uint64(diskId.(int)), + } + + _, err := c.CloudBroker().Compute().DiskAttach(ctx, req) if err != nil { // failed to attach disk - there will be partial resource update log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err) @@ -129,13 +126,8 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa } func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error { - // "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key - // If do_delta is true, this function will identify changes between new and existing specs for network and try to - // update compute configuration accordingly - // Otherwise it will apply whatever is found in the new set of "network" right away. - // Primary use of do_delta=false is when calling this function from compute Create handler. - c := m.(*controller.ControllerCfg) + computeID, _ := strconv.ParseUint(d.Id(), 10, 64) old_set, new_set := d.GetChange("network") @@ -148,18 +140,19 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData } for _, runner := range new_set.(*schema.Set).List() { - urlValues := &url.Values{} net_data := runner.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("netType", net_data["net_type"].(string)) - urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int))) - ipaddr, ipSet := net_data["ip_address"] // "ip_address" key is optional + req := compute.NetAttachRequest{ + ComputeID: computeID, + NetType: net_data["net_type"].(string), + NetID: uint64(net_data["net_id"].(int)), + } + + ipaddr, ipSet := net_data["ip_address"] if ipSet { - urlValues.Add("ipAddr", ipaddr.(string)) + req.IPAddr = ipaddr.(string) } - _, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues) + _, err := c.CloudBroker().Compute().NetAttach(ctx, req) if err != nil { - // failed to attach network - partial resource update apiErrCount++ lastSavedError = err } @@ -176,12 +169,14 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set)) log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id()) for _, runner := range detach_set.List() { - urlValues := &url.Values{} net_data := runner.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("ipAddr", net_data["ip_address"].(string)) - urlValues.Add("mac", net_data["mac"].(string)) - _, err := c.DecortAPICall(ctx, "POST", ComputeNetDetachAPI, urlValues) + req := compute.NetDetachRequest{ + ComputeID: computeID, + IPAddr: net_data["ip_address"].(string), + MAC: net_data["mac"].(string), + } + + _, err := c.CloudBroker().Compute().NetDetach(ctx, req) if err != nil { // failed to detach this network - there will be partial resource update log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s", @@ -194,15 +189,18 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set)) log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id()) for _, runner := range attach_set.List() { - urlValues := &url.Values{} net_data := runner.(map[string]interface{}) - urlValues.Add("computeId", d.Id()) - urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int))) - urlValues.Add("netType", net_data["net_type"].(string)) + req := compute.NetAttachRequest{ + ComputeID: computeID, + NetID: uint64(net_data["net_id"].(int)), + NetType: net_data["net_type"].(string), + } + if net_data["ip_address"].(string) != "" { - urlValues.Add("ipAddr", net_data["ip_address"].(string)) + req.IPAddr = net_data["ip_address"].(string) } - _, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues) + + _, err := c.CloudBroker().Compute().NetAttach(ctx, req) if err != nil { // failed to attach this network - there will be partial resource update log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s", @@ -221,31 +219,15 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData return nil } -func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { - // This function tries to locate Compute by one of the following approaches: - // - if compute_id is specified - locate by compute ID - // - if compute_name is specified - locate by a combination of compute name and resource - // group ID - // - // If succeeded, it returns non-empty string that contains JSON formatted facts about the - // Compute as returned by compute/get API call. - // Otherwise it returns empty string and meaningful error. - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for resource's Exists method. - // - +func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.RecordCompute, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - // make it possible to use "read" & "check presence" functions with compute ID set so - // that Import of Compute resource is possible idSet := false - theId, err := strconv.Atoi(d.Id()) - if err != nil || theId <= 0 { + computeID, err := strconv.ParseUint(d.Id(), 10, 64) + if err != nil || computeID <= 0 { computeId, argSet := d.GetOk("compute_id") // NB: compute_id is NOT present in computeResource schema! if argSet { - theId = computeId.(int) + computeID = uint64(computeId.(int)) idSet = true } } else { @@ -254,11 +236,14 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m if idSet { // compute ID is specified, try to get compute instance straight by this ID - log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", theId) - urlValues.Add("computeId", fmt.Sprintf("%d", theId)) - computeFacts, err := c.DecortAPICall(ctx, "POST", ComputeGetAPI, urlValues) + log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", computeID) + req := compute.GetRequest{ + ComputeID: computeID, + } + + computeFacts, err := c.CloudBroker().Compute().Get(ctx, req) if err != nil { - return "", err + return nil, err } return computeFacts, nil } @@ -267,44 +252,40 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m // and RG ID computeName, argSet := d.GetOk("name") if !argSet { - return "", fmt.Errorf("Cannot locate compute instance if name is empty and no compute ID specified") + return nil, fmt.Errorf("Cannot locate compute instance if name is empty and no compute ID specified") } rgId, argSet := d.GetOk("rg_id") if !argSet { - return "", fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string)) + return nil, fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string)) } - urlValues.Add("rgId", fmt.Sprintf("%d", rgId)) - apiResp, err := c.DecortAPICall(ctx, "POST", RgListComputesAPI, urlValues) - if err != nil { - return "", err + rgListComputesReq := rg.ListComputesRequest{ + RGID: uint64(rgId.(int)), } - log.Debugf("utilityComputeCheckPresence: ready to unmarshal string %s", apiResp) - - computeList := RgListComputesResp{} - err = json.Unmarshal([]byte(apiResp), &computeList) + computeList, err := c.CloudBroker().RG().ListComputes(ctx, rgListComputesReq) if err != nil { - return "", err + return nil, err } - // log.Printf("%#v", computeList) log.Debugf("utilityComputeCheckPresence: traversing decoded JSON of length %d", len(computeList)) for index, item := range computeList { // need to match Compute by name, skip Computes with the same name in DESTROYED satus if item.Name == computeName.(string) && item.Status != "DESTROYED" { log.Debugf("utilityComputeCheckPresence: index %d, matched name %s", index, item.Name) // we found the Compute we need - now get detailed information via compute/get API - cgetValues := &url.Values{} - cgetValues.Add("computeId", fmt.Sprintf("%d", item.ID)) - apiResp, err = c.DecortAPICall(ctx, "POST", ComputeGetAPI, cgetValues) + req := compute.GetRequest{ + ComputeID: item.ID, + } + + apiResp, err := c.CloudBroker().Compute().Get(ctx, req) if err != nil { - return "", err + return nil, err } return apiResp, nil } } - return "", nil // there should be no error if Compute does not exist + return nil, nil } diff --git a/internal/service/cloudbroker/pcidevice/api.go b/internal/service/cloudbroker/pcidevice/api.go deleted file mode 100644 index 7b66fe2..0000000 --- a/internal/service/cloudbroker/pcidevice/api.go +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package pcidevice - -const pcideviceListAPI = "/restmachine/cloudbroker/pcidevice/list" -const pcideviceDisableAPI = "/restmachine/cloudbroker/pcidevice/disable" -const pcideviceEnableAPI = "/restmachine/cloudbroker/pcidevice/enable" -const pcideviceCreateAPI = "/restmachine/cloudbroker/pcidevice/create" -const pcideviceDeleteAPI = "/restmachine/cloudbroker/pcidevice/delete" diff --git a/internal/service/cloudbroker/pcidevice/data_source_pcidevice.go b/internal/service/cloudbroker/pcidevice/data_source_pcidevice.go index abb822b..bb927b9 100644 --- a/internal/service/cloudbroker/pcidevice/data_source_pcidevice.go +++ b/internal/service/cloudbroker/pcidevice/data_source_pcidevice.go @@ -49,11 +49,11 @@ func dataSourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m inte d.Set("ckey", pcidevice.CKey) d.Set("meta", flattens.FlattenMeta(pcidevice.Meta)) - d.Set("compute_id", pcidevice.Computeid) + d.Set("compute_id", pcidevice.ComputeID) d.Set("description", pcidevice.Description) - d.Set("guid", pcidevice.Guid) + d.Set("guid", pcidevice.GUID) d.Set("hw_path", pcidevice.HwPath) - d.Set("rg_id", pcidevice.RgID) + d.Set("rg_id", pcidevice.RGID) d.Set("name", pcidevice.Name) d.Set("stack_id", pcidevice.StackID) d.Set("status", pcidevice.Status) diff --git a/internal/service/cloudbroker/pcidevice/data_source_pcidevice_list.go b/internal/service/cloudbroker/pcidevice/data_source_pcidevice_list.go index fdf1e27..e5496c1 100644 --- a/internal/service/cloudbroker/pcidevice/data_source_pcidevice_list.go +++ b/internal/service/cloudbroker/pcidevice/data_source_pcidevice_list.go @@ -37,22 +37,23 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) -func flattenPcideviceList(pl PcideviceList) []map[string]interface{} { +func flattenPcideviceList(pl pcidevice.ListPCIDevices) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, item := range pl { temp := map[string]interface{}{ "ckey": item.CKey, "meta": flattens.FlattenMeta(item.Meta), - "compute_id": item.Computeid, + "compute_id": item.ComputeID, "description": item.Description, - "guid": item.Guid, + "guid": item.GUID, "hw_path": item.HwPath, "device_id": item.ID, - "rg_id": item.RgID, + "rg_id": item.RGID, "name": item.Name, "stack_id": item.StackID, "status": item.Status, diff --git a/internal/service/cloudbroker/pcidevice/models.go b/internal/service/cloudbroker/pcidevice/models.go deleted file mode 100644 index e33c772..0000000 --- a/internal/service/cloudbroker/pcidevice/models.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package pcidevice - -type Pcidevice struct { - CKey string `json:"_ckey"` - Meta []interface{} `json:"_meta"` - Computeid int `json:"computeId"` - Description string `json:"description"` - Guid int `json:"guid"` - HwPath string `json:"hwPath"` - ID int `json:"id"` - Name string `json:"name"` - RgID int `json:"rgId"` - StackID int `json:"stackId"` - Status string `json:"status"` - SystemName string `json:"systemName"` -} - -type PcideviceList []Pcidevice diff --git a/internal/service/cloudbroker/pcidevice/resource_pcidevice.go b/internal/service/cloudbroker/pcidevice/resource_pcidevice.go index e5b99f2..bd80c7a 100644 --- a/internal/service/cloudbroker/pcidevice/resource_pcidevice.go +++ b/internal/service/cloudbroker/pcidevice/resource_pcidevice.go @@ -33,45 +33,41 @@ package pcidevice import ( "context" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" - log "github.com/sirupsen/logrus" ) func resourcePcideviceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourcePcideviceCreate: called for pcidevice %s", d.Get("name").(string)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("hwPath", d.Get("hw_path").(string)) - urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int))) - urlValues.Add("stackId", strconv.Itoa(d.Get("stack_id").(int))) + req := pcidevice.CreateRequest{ + Name: d.Get("name").(string), + HWPath: d.Get("hw_path").(string), + RGID: uint64(d.Get("rg_id").(int)), + StackID: uint64(d.Get("stack_id").(int)), + } if description, ok := d.GetOk("description"); ok { - urlValues.Add("description", description.(string)) + req.Description = description.(string) } - pcideviceId, err := c.DecortAPICall(ctx, "POST", pcideviceCreateAPI, urlValues) + pcideviceId, err := c.CloudBroker().PCIDevice().Create(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(pcideviceId) + d.SetId(strconv.FormatUint(pcideviceId, 10)) d.Set("device_id", pcideviceId) - diagnostics := resourcePcideviceRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourcePcideviceRead(ctx, d, m) } func resourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -80,15 +76,14 @@ func resourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m interf return diag.FromErr(err) } - d.SetId(strconv.Itoa(pcidevice.ID)) d.Set("ckey", pcidevice.CKey) d.Set("meta", flattens.FlattenMeta(pcidevice.Meta)) - d.Set("compute_id", pcidevice.Computeid) + d.Set("compute_id", pcidevice.ComputeID) d.Set("description", pcidevice.Description) - d.Set("guid", pcidevice.Guid) + d.Set("guid", pcidevice.GUID) d.Set("hw_path", pcidevice.HwPath) d.Set("device_id", pcidevice.ID) - d.Set("rg_id", pcidevice.RgID) + d.Set("rg_id", pcidevice.RGID) d.Set("name", pcidevice.Name) d.Set("stack_id", pcidevice.StackID) d.Set("status", pcidevice.Status) @@ -101,11 +96,13 @@ func resourcePcideviceDelete(ctx context.Context, d *schema.ResourceData, m inte log.Debugf("resourcePcideviceDelete: called for %s, id: %s", d.Get("name").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("deviceId", d.Id()) - urlValues.Add("force", strconv.FormatBool(d.Get("force").(bool))) + deviceID, _ := strconv.ParseUint(d.Id(), 10, 64) + req := pcidevice.DeleteRequest{ + DeviceID: deviceID, + Force: d.Get("force").(bool), + } - _, err := c.DecortAPICall(ctx, "POST", pcideviceDeleteAPI, urlValues) + _, err := c.CloudBroker().PCIDevice().Delete(ctx, req) if err != nil { return diag.FromErr(err) } @@ -115,33 +112,33 @@ func resourcePcideviceDelete(ctx context.Context, d *schema.ResourceData, m inte return nil } -func resourcePcideviceEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourcePcideviceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { if d.HasChange("enable") { state := d.Get("enable").(bool) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - api := "" - - urlValues.Add("deviceId", strconv.Itoa(d.Get("device_id").(int))) if state { - api = pcideviceEnableAPI + req := pcidevice.EnableRequest{ + DeviceID: uint64(d.Get("device_id").(int)), + } + + _, err := c.CloudBroker().PCIDevice().Enable(ctx, req) + if err != nil { + return diag.FromErr(err) + } } else { - api = pcideviceDisableAPI - } - - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return diag.FromErr(err) + req := pcidevice.DisableRequest{ + DeviceID: uint64(d.Get("device_id").(int)), + } + + _, err := c.CloudBroker().PCIDevice().Disable(ctx, req) + if err != nil { + return diag.FromErr(err) + } } } - diagnostics := resourcePcideviceRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourcePcideviceRead(ctx, d, m) } func resourcePcideviceSchemaMake() map[string]*schema.Schema { @@ -225,7 +222,7 @@ func ResourcePcidevice() *schema.Resource { CreateContext: resourcePcideviceCreate, ReadContext: resourcePcideviceRead, - UpdateContext: resourcePcideviceEdit, + UpdateContext: resourcePcideviceUpdate, DeleteContext: resourcePcideviceDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudbroker/pcidevice/utility_pcidevice.go b/internal/service/cloudbroker/pcidevice/utility_pcidevice.go index 9e311e0..1dea551 100644 --- a/internal/service/cloudbroker/pcidevice/utility_pcidevice.go +++ b/internal/service/cloudbroker/pcidevice/utility_pcidevice.go @@ -36,19 +36,20 @@ import ( "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" ) -func utilityPcideviceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Pcidevice, error) { +func utilityPcideviceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*pcidevice.ItemPCIDevice, error) { pcideviceList, err := utilityPcideviceListCheckPresence(ctx, m) if err != nil { return nil, err } - pcideviceId := 0 + var pcideviceId uint64 if (d.Get("device_id").(int)) != 0 { - pcideviceId = d.Get("device_id").(int) + pcideviceId = uint64(d.Get("device_id").(int)) } else { - id, _ := strconv.Atoi(d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) pcideviceId = id } diff --git a/internal/service/cloudbroker/pcidevice/utility_pcidevice_list.go b/internal/service/cloudbroker/pcidevice/utility_pcidevice_list.go index 927dd1d..09aa578 100644 --- a/internal/service/cloudbroker/pcidevice/utility_pcidevice_list.go +++ b/internal/service/cloudbroker/pcidevice/utility_pcidevice_list.go @@ -33,23 +33,15 @@ package pcidevice import ( "context" - "encoding/json" - "net/url" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityPcideviceListCheckPresence(ctx context.Context, m interface{}) (PcideviceList, error) { - pcideviceList := PcideviceList{} +func utilityPcideviceListCheckPresence(ctx context.Context, m interface{}) (pcidevice.ListPCIDevices, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - pcideviceListRaw, err := c.DecortAPICall(ctx, "POST", pcideviceListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(pcideviceListRaw), &pcideviceList) + pcideviceList, err := c.CloudBroker().PCIDevice().List(ctx) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/pfw/models.go b/internal/service/cloudbroker/pfw/models.go deleted file mode 100644 index 30f643d..0000000 --- a/internal/service/cloudbroker/pfw/models.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package pfw -type PfwRecord struct { - ID int `json:"id"` - LocalIP string `json:"localIp"` - LocalPort int `json:"localPort"` - Protocol string `json:"protocol"` - PublicPortEnd int `json:"publicPortEnd"` - PublicPortStart int `json:"publicPortStart"` - ComputeID int `json:"vmId"` -} - -type ComputePfwListResp []PfwRecord - - diff --git a/internal/service/cloudbroker/pfw/resource_pfw.go b/internal/service/cloudbroker/pfw/resource_pfw.go index cd03c79..9c0a00b 100644 --- a/internal/service/cloudbroker/pfw/resource_pfw.go +++ b/internal/service/cloudbroker/pfw/resource_pfw.go @@ -34,37 +34,36 @@ package pfw import ( "context" "fmt" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourcePfwCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("publicPortStart", strconv.Itoa(d.Get("public_port_start").(int))) - urlValues.Add("localBasePort", strconv.Itoa(d.Get("local_base_port").(int))) - urlValues.Add("proto", d.Get("proto").(string)) + req := compute.PFWAddRequest{} + req.ComputeID = uint64(d.Get("compute_id").(int)) + req.PublicPortStart = uint64(d.Get("public_port_start").(int)) + req.LocalBasePort = uint64(d.Get("local_base_port").(int)) + req.Proto = d.Get("proto").(string) if portEnd, ok := d.GetOk("public_port_end"); ok { - urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int))) + req.PublicPortEnd = uint64(portEnd.(int)) } - pfwId, err := c.DecortAPICall(ctx, "POST", ComputePfwAddAPI, urlValues) + pfwId, err := c.CloudBroker().Compute().PFWAdd(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(fmt.Sprintf("%d-%s", d.Get("compute_id").(int), pfwId)) + d.SetId(fmt.Sprintf("%d-%d", d.Get("compute_id").(int), pfwId)) pfw, err := utilityPfwCheckPresence(ctx, d, m) if err != nil { @@ -88,7 +87,7 @@ func resourcePfwRead(ctx context.Context, d *schema.ResourceData, m interface{}) return diag.FromErr(err) } - d.Set("compute_id", pfw.ComputeID) + d.Set("compute_id", pfw.VMID) d.Set("public_port_start", pfw.PublicPortStart) d.Set("public_port_end", pfw.PublicPortEnd) d.Set("local_ip", pfw.LocalIP) @@ -110,15 +109,18 @@ func resourcePfwDelete(ctx context.Context, d *schema.ResourceData, m interface{ } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("ruleId", strconv.Itoa(pfw.ID)) + req := compute.PFWDelRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + RuleID: pfw.ID, + } - _, err = c.DecortAPICall(ctx, "POST", ComputePfwDelAPI, urlValues) + _, err = c.CloudBroker().Compute().PFWDel(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") + return nil } diff --git a/internal/service/cloudbroker/pfw/utility_pfw.go b/internal/service/cloudbroker/pfw/utility_pfw.go index a9bb4bf..d04462b 100644 --- a/internal/service/cloudbroker/pfw/utility_pfw.go +++ b/internal/service/cloudbroker/pfw/utility_pfw.go @@ -33,42 +33,33 @@ package pfw import ( "context" - "encoding/json" - "net/url" "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*PfwRecord, error) { +func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemPFW, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := compute.PFWListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + } - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - resp, err := c.DecortAPICall(ctx, "POST", ComputePfwListAPI, urlValues) + pfws, err := c.CloudBroker().Compute().PFWList(ctx, req) if err != nil { return nil, err } - if resp == "" { - return nil, nil - } - idS := strings.Split(d.Id(), "-")[1] id, err := strconv.Atoi(idS) if err != nil { return nil, err } - var pfws []PfwRecord - if err := json.Unmarshal([]byte(resp), &pfws); err != nil { - return nil, err - } - for _, pfw := range pfws { - if pfw.ID == id { + if pfw.ID == uint64(id) { return &pfw, nil } } diff --git a/internal/service/cloudbroker/rg/data_source_rg.go b/internal/service/cloudbroker/rg/data_source_rg.go index d977539..2c6b1fc 100644 --- a/internal/service/cloudbroker/rg/data_source_rg.go +++ b/internal/service/cloudbroker/rg/data_source_rg.go @@ -33,58 +33,42 @@ package rg import ( "context" - "encoding/json" "fmt" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" log "github.com/sirupsen/logrus" - - // "net/url" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func flattenResgroup(d *schema.ResourceData, rg_facts string) error { - // NOTE: this function modifies ResourceData argument - as such it should never be called - // from resourceRsgroupExists(...) method - // log.Debugf("%s", rg_facts) - log.Debugf("flattenResgroup: ready to decode response body from API") - details := ResgroupGetResp{} - err := json.Unmarshal([]byte(rg_facts), &details) - if err != nil { - return err - } - +func flattenResgroup(d *schema.ResourceData, rgData *rg.RecordRG) error { log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d", - details.Name, details.ID, details.AccountID) - - d.SetId(fmt.Sprintf("%d", details.ID)) - d.Set("rg_id", details.ID) - d.Set("name", details.Name) - d.Set("account_name", details.AccountName) - d.Set("account_id", details.AccountID) - // d.Set("grid_id", details.GridID) - d.Set("description", details.Desc) - d.Set("status", details.Status) - d.Set("def_net_type", details.DefaultNetType) - d.Set("def_net_id", details.DefaultNetID) - /* - d.Set("vins", details.Vins) - d.Set("computes", details.Computes) - */ - - log.Debugf("flattenResgroup: calling flattenQuota()") - if err = d.Set("quota", parseQuota(details.Quota)); err != nil { - return err - } + rgData.Name, rgData.ID, rgData.AccountID) + + d.SetId(fmt.Sprintf("%d", rgData.ID)) + d.Set("rg_id", rgData.ID) + d.Set("name", rgData.Name) + d.Set("account_name", rgData.AccountName) + d.Set("account_id", rgData.AccountID) + // d.Set("grid_id", rgData.GridID) + d.Set("description", rgData.Description) + d.Set("status", rgData.Status) + d.Set("def_net_type", rgData.DefNetType) + d.Set("def_net_id", rgData.DefNetID) + + // log.Debugf("flattenResgroup: calling flattenQuota()") + // if err := d.Set("quota", parseQuota(rgData.Resources)); err != nil { + // return err + // } return nil } func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { rg_facts, err := utilityResgroupCheckPresence(ctx, d, m) - if rg_facts == "" { + if rg_facts == nil { // if empty string is returned from utilityResgroupCheckPresence then there is no // such resource group and err tells so - just return it to the calling party d.SetId("") // ensure ID is empty in this case diff --git a/internal/service/cloudbroker/rg/data_source_rg_list.go b/internal/service/cloudbroker/rg/data_source_rg_list.go index 2210a4d..3446668 100644 --- a/internal/service/cloudbroker/rg/data_source_rg_list.go +++ b/internal/service/cloudbroker/rg/data_source_rg_list.go @@ -37,24 +37,25 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenRgList(rgl ResgroupListResp) []map[string]interface{} { +func flattenRgList(rgl rg.ListRG) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rg := range rgl { temp := map[string]interface{}{ "account_id": rg.AccountID, "account_name": rg.AccountName, - "acl": flattenRgAcl(rg.ACLs), + "acl": flattenRgAcl(rg.ACL), "created_by": rg.CreatedBy, "created_time": rg.CreatedTime, - "def_net_id": rg.DefaultNetID, - "def_net_type": rg.DefaultNetType, + "def_net_id": rg.DefNetID, + "def_net_type": rg.DefNetType, "deleted_by": rg.DeletedBy, "deleted_time": rg.DeletedTime, - "desc": rg.Decsription, - "gid": rg.GridID, + "desc": rg.Description, + "gid": rg.GID, "guid": rg.GUID, "rg_id": rg.ID, "lock_status": rg.LockStatus, @@ -66,8 +67,8 @@ func flattenRgList(rgl ResgroupListResp) []map[string]interface{} { "status": rg.Status, "updated_by": rg.UpdatedBy, "updated_time": rg.UpdatedTime, - "vins": rg.Vins, - "vms": rg.Computes, + "vins": rg.VINS, + "vms": rg.VMs, } res = append(res, temp) } @@ -75,31 +76,31 @@ func flattenRgList(rgl ResgroupListResp) []map[string]interface{} { } -func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} { +func flattenRgAcl(rgAcls rg.ListACL) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, rgAcl := range rgAcls { temp := map[string]interface{}{ - "explicit": rgAcl.IsExplicit, - "guid": rgAcl.Guid, - "right": rgAcl.Rights, + "explicit": rgAcl.Explicit, + "guid": rgAcl.GUID, + "right": rgAcl.Right, "status": rgAcl.Status, "type": rgAcl.Type, - "user_group_id": rgAcl.UgroupID, + "user_group_id": rgAcl.UserGroupID, } res = append(res, temp) } return res } -func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} { +func flattenRgResourceLimits(rl rg.ResourceLimits) []map[string]interface{} { res := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "cu_c": rl.CUC, - "cu_d": rl.CUD, + "cu_d": rl.CuD, "cu_i": rl.CUI, "cu_m": rl.CUM, "cu_np": rl.CUNP, - "gpu_units": rl.GpuUnits, + "gpu_units": rl.GPUUnits, } res = append(res, temp) diff --git a/internal/service/cloudbroker/rg/models.go b/internal/service/cloudbroker/rg/models.go index d97a388..49d6a1c 100644 --- a/internal/service/cloudbroker/rg/models.go +++ b/internal/service/cloudbroker/rg/models.go @@ -126,12 +126,12 @@ type UserAclRecord struct { } type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get - Cpu int `json:"CU_C"` // CPU count in pcs + Cpu float64 `json:"CU_C"` // CPU count in pcs Ram float64 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT - Disk int `json:"CU_D"` // Disk capacity in GB - ExtIPs int `json:"CU_I"` // Ext IPs count - ExtTraffic int `json:"CU_NP"` // Ext network traffic - GpuUnits int `json:"gpu_units"` // GPU count + Disk float64 `json:"CU_D"` // Disk capacity in GB + ExtIPs float64 `json:"CU_I"` // Ext IPs count + ExtTraffic float64 `json:"CU_NP"` // Ext network traffic + GpuUnits float64 `json:"gpu_units"` // GPU count } type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get diff --git a/internal/service/cloudbroker/rg/quota_subresource.go b/internal/service/cloudbroker/rg/quota_subresource.go index a7cd202..c0c4293 100644 --- a/internal/service/cloudbroker/rg/quota_subresource.go +++ b/internal/service/cloudbroker/rg/quota_subresource.go @@ -33,6 +33,7 @@ package rg import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" ) func makeQuotaRecord(arg_list []interface{}) QuotaRecord { @@ -47,41 +48,41 @@ func makeQuotaRecord(arg_list []interface{}) QuotaRecord { subres_data := arg_list[0].(map[string]interface{}) if subres_data["cpu"].(int) > 0 { - quota.Cpu = subres_data["cpu"].(int) + quota.Cpu = subres_data["cpu"].(float64) } if subres_data["disk"].(int) > 0 { - quota.Disk = subres_data["disk"].(int) // Disk capacity ib GB + quota.Disk = subres_data["disk"].(float64) } if subres_data["ram"].(float64) > 0 { - quota.Ram = subres_data["ram"].(float64) // RAM volume in MB, as float64! + quota.Ram = subres_data["ram"].(float64) } if subres_data["ext_traffic"].(int) > 0 { - quota.ExtTraffic = subres_data["ext_traffic"].(int) + quota.ExtTraffic = subres_data["ext_traffic"].(float64) } if subres_data["ext_ips"].(int) > 0 { - quota.ExtIPs = subres_data["ext_ips"].(int) + quota.ExtIPs = subres_data["ext_ips"].(float64) } if subres_data["gpu_units"].(int) > 0 { - quota.GpuUnits = subres_data["gpu_units"].(int) + quota.GpuUnits = subres_data["gpu_units"].(float64) } return quota } -func parseQuota(quota QuotaRecord) []interface{} { +func parseQuota(quota rg.ResourceLimits) []interface{} { quota_map := make(map[string]interface{}) - quota_map["cpu"] = quota.Cpu - quota_map["ram"] = quota.Ram // NB: this is float64, unlike the rest of values - quota_map["disk"] = quota.Disk - quota_map["ext_traffic"] = quota.ExtTraffic - quota_map["ext_ips"] = quota.ExtIPs - quota_map["gpu_units"] = quota.GpuUnits + quota_map["cpu"] = quota.CUC + quota_map["ram"] = quota.CUM + quota_map["disk"] = quota.CuD + quota_map["ext_traffic"] = quota.CUNP + quota_map["ext_ips"] = quota.CUI + quota_map["gpu_units"] = quota.GPUUnits result := make([]interface{}, 1) result[0] = quota_map @@ -92,7 +93,7 @@ func parseQuota(quota QuotaRecord) []interface{} { func quotaRgSubresourceSchemaMake() map[string]*schema.Schema { rets := map[string]*schema.Schema{ "cpu": { - Type: schema.TypeInt, + Type: schema.TypeFloat, Optional: true, Default: -1, Description: "Limit on the total number of CPUs in this resource group.", @@ -106,28 +107,28 @@ func quotaRgSubresourceSchemaMake() map[string]*schema.Schema { }, "disk": { - Type: schema.TypeInt, + Type: schema.TypeFloat, Optional: true, Default: -1, Description: "Limit on the total volume of storage resources in this resource group, specified in GB.", }, "ext_traffic": { - Type: schema.TypeInt, + Type: schema.TypeFloat, Optional: true, Default: -1, Description: "Limit on the total ingress network traffic for this resource group, specified in GB.", }, "ext_ips": { - Type: schema.TypeInt, + Type: schema.TypeFloat, Optional: true, Default: -1, Description: "Limit on the total number of external IP addresses this resource group can use.", }, "gpu_units": { - Type: schema.TypeInt, + Type: schema.TypeFloat, Optional: true, Default: -1, Description: "Limit on the total number of virtual GPUs this resource group can use.", diff --git a/internal/service/cloudbroker/rg/resource_rg.go b/internal/service/cloudbroker/rg/resource_rg.go index e938087..6525aa3 100644 --- a/internal/service/cloudbroker/rg/resource_rg.go +++ b/internal/service/cloudbroker/rg/resource_rg.go @@ -33,14 +33,14 @@ package rg import ( "context" - "encoding/json" "fmt" - "net/url" + "strconv" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/location" - log "github.com/sirupsen/logrus" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -48,32 +48,13 @@ import ( ) func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - // First validate that we have all parameters required to create the new Resource Group - - // Valid account ID is required to create new resource group - // obtain Account ID by account name - it should not be zero on success - rg_name, arg_set := d.GetOk("name") if !arg_set { return diag.FromErr(fmt.Errorf("Cannot create new RG: missing name.")) } - - /* Current version of provider works with default grid id (same is true for disk resources) - grid_id, arg_set := d.GetOk("grid_id") - if !arg_set { - return fmt.Errorf("Cannot create new RG %q in account ID %d: missing Grid ID.", - rg_name.(string), validated_account_id) - } - if grid_id.(int) < 1 { - grid_id = DefaultGridID - } - */ - - // all required parameters are set in the schema - we can continue with RG creation log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d", rg_name.(string), d.Get("account_id").(int)) - // quota settings are optional set_quota := false var quota_record QuotaRecord arg_value, arg_set := d.GetOk("quota") @@ -88,62 +69,57 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter c.GetDecortUsername(), rg_name.(string), d.Get("account_id").(int)) - url_values := &url.Values{} - url_values.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int))) - url_values.Add("name", rg_name.(string)) - url_values.Add("gid", fmt.Sprintf("%d", location.DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention - url_values.Add("owner", c.GetDecortUsername()) + req := rg.CreateRequest{ + AccountID: uint64(d.Get("account_id").(int)), + Name: rg_name.(string), + GID: uint64(location.DefaultGridID), + Owner: c.GetDecortUsername(), + } // pass quota values as set if set_quota { - url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quota_record.Cpu)) - url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quota_record.Disk)) - url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quota_record.Ram)) // RAM quota is float; this may change in the future - url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quota_record.ExtTraffic)) - url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quota_record.ExtIPs)) + req.MaxCPUCapacity = int64(quota_record.Cpu) + req.MaxVDiskCapacity = int64(quota_record.Disk) + req.MaxMemoryCapacity = int64(quota_record.Ram) + req.MaxNetworkPeerTransfer = int64(quota_record.ExtTraffic) + req.MaxNumPublicIP = int64(quota_record.ExtIPs) // url_values.Add("???", fmt.Sprintf("%d", quota_record.GpuUnits)) } // parse and handle network settings def_net_type, arg_set := d.GetOk("def_net_type") if arg_set { - url_values.Add("def_net", def_net_type.(string)) // NOTE: in API default network type is set by "def_net" parameter + req.DefNet = def_net_type.(string) } ipcidr, arg_set := d.GetOk("ipcidr") if arg_set { - url_values.Add("ipcidr", ipcidr.(string)) + req.IPCIDR = ipcidr.(string) } ext_net_id, arg_set := d.GetOk("ext_net_id") if arg_set { - url_values.Add("extNetId", fmt.Sprintf("%d", ext_net_id.(int))) + req.ExtNetID = uint64(ext_net_id.(int)) } ext_ip, arg_set := d.GetOk("ext_ip") if arg_set { - url_values.Add("extIp", ext_ip.(string)) + req.ExtIP = ext_ip.(string) } - api_resp, err := c.DecortAPICall(ctx, "POST", ResgroupCreateAPI, url_values) + rgId, err := c.CloudBroker().RG().Create(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(api_resp) // rg/create API returns ID of the newly creted resource group on success - // rg.ID, _ = strconv.Atoi(api_resp) + d.SetId(strconv.FormatUint(rgId, 10)) if !set_quota { resp, err := utilityResgroupCheckPresence(ctx, d, m) if err != nil { return diag.FromErr(err) } - rg := ResgroupGetResp{} - if err := json.Unmarshal([]byte(resp), &rg); err != nil { - return diag.FromErr(err) - } - - d.Set("quota", parseQuota(rg.Quota)) + d.Set("quota", parseQuota(resp.ResourceLimits)) } // re-read newly created RG to make sure schema contains complete and up to date set of specifications @@ -155,9 +131,7 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa d.Get("name").(string), d.Get("account_id").(int)) rg_facts, err := utilityResgroupCheckPresence(ctx, d, m) - if rg_facts == "" { - // if empty string is returned from utilityResgroupCheckPresence then there is no - // such resource group and err tells so - just return it to the calling party + if rg_facts == nil { d.SetId("") // ensure ID is empty return diag.FromErr(err) } @@ -192,8 +166,10 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter do_general_update := false // will be true if general RG update is necessary (API rg/update) c := m.(*controller.ControllerCfg) - url_values := &url.Values{} - url_values.Add("rgId", d.Id()) + rgId, _ := strconv.ParseUint(d.Id(), 10, 64) + req := rg.UpdateRequest{ + RGID: rgId, + } name_new, name_set := d.GetOk("name") if name_set { @@ -201,7 +177,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter name_old, _ := d.GetChange("name") if name_old.(string) != name_new.(string) { do_general_update = true - url_values.Add("name", name_new.(string)) + req.Name = name_new.(string) } } @@ -215,31 +191,31 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter if quotarecord_new.Cpu != quotarecord_old.Cpu { do_general_update = true log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu) - url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu)) + req.MaxCPUCapacity = int64(quotarecord_new.Cpu) } if quotarecord_new.Disk != quotarecord_old.Disk { do_general_update = true log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk) - url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk)) + req.MaxVDiskCapacity = int64(quotarecord_new.Disk) } if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB do_general_update = true log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram) - url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram)) + req.MaxMemoryCapacity = int64(quotarecord_new.Ram) } if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic { do_general_update = true log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic) - url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic)) + req.MaxNetworkPeerTransfer = int64(quotarecord_new.ExtTraffic) } if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs { do_general_update = true log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs) - url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs)) + req.MaxNumPublicIP = int64(quotarecord_new.ExtIPs) } } @@ -249,13 +225,13 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter desc_old, _ := d.GetChange("description") if desc_old.(string) != desc_new.(string) { do_general_update = true - url_values.Add("desc", desc_new.(string)) + req.Description = desc_new.(string) } } if do_general_update { log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG") - _, err := c.DecortAPICall(ctx, "POST", ResgroupUpdateAPI, url_values) + _, err := c.CloudBroker().RG().Update(ctx, req) if err != nil { return diag.FromErr(err) } @@ -267,29 +243,26 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter } func resourceResgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - // NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to - // restore the destroyed resource group as well all Computes & VINSes that existed in it log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d", d.Get("name").(string), d.Get("account_id").(int)) rg_facts, err := utilityResgroupCheckPresence(ctx, d, m) - if rg_facts == "" { + if rg_facts == nil { if err != nil { return diag.FromErr(err) } - // the target RG does not exist - in this case according to Terraform best practice - // we exit from Destroy method without error return nil } - url_values := &url.Values{} - url_values.Add("rgId", d.Id()) - url_values.Add("force", "1") - url_values.Add("permanently", "1") - url_values.Add("reason", "Destroyed by DECORT Terraform provider") + req := rg.DeleteRequest{ + RGID: rg_facts.ID, + Force: true, + Permanently: true, + Reason: "Destroyed by DECORT Terraform provider", + } c := m.(*controller.ControllerCfg) - _, err = c.DecortAPICall(ctx, "POST", ResgroupDeleteAPI, url_values) + _, err = c.CloudBroker().RG().Delete(ctx, req) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudbroker/rg/utility_rg.go b/internal/service/cloudbroker/rg/utility_rg.go index 9057bf0..949b139 100644 --- a/internal/service/cloudbroker/rg/utility_rg.go +++ b/internal/service/cloudbroker/rg/utility_rg.go @@ -33,48 +33,25 @@ package rg import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -// On success this function returns a string, as returned by API rg/get, which could be unmarshalled -// into ResgroupGetResp structure -func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { - // This function tries to locate resource group by one of the following algorithms depending - // on the parameters passed: - // - if resource group ID is specified -> by RG ID - // - if resource group name is specifeid -> by RG name and either account ID or account name - // - // If succeeded, it returns non empty string that contains JSON formatted facts about the - // resource group as returned by rg/get API call. - // Otherwise it returns empty string and a meaningful error. - // - // NOTE: As our provider always deletes RGs permanently, there is no "restore" method and - // consequently we are not interested in matching RGs in DELETED state. Hence, we call - // .../rg/list API with includedeleted=false - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for the Terraform resource Exists method. - // - +func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordRG, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - // make it possible to use "read" & "check presence" functions with RG ID set so - // that Import of RG resource is possible idSet := false - theId, err := strconv.Atoi(d.Id()) + theId, err := strconv.ParseUint(d.Id(), 10, 64) if err != nil || theId <= 0 { rgId, argSet := d.GetOk("rg_id") if argSet { - theId = rgId.(int) + theId = uint64(rgId.(int)) idSet = true } } else { @@ -82,58 +59,50 @@ func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m } if idSet { - // go straight for the RG by its ID log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId) - urlValues.Add("rgId", fmt.Sprintf("%d", theId)) - rgFacts, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, urlValues) + req := rg.GetRequest{ + RGID: theId, + } + + rgFacts, err := c.CloudBroker().RG().Get(ctx, req) if err != nil { - return "", err + return nil, err } return rgFacts, nil } rgName, argSet := d.GetOk("name") if !argSet { - // no RG ID and no RG name - we cannot locate resource group in this case - return "", fmt.Errorf("Cannot check resource group presence if name is empty and no resource group ID specified") + return nil, fmt.Errorf("Cannot check resource group presence if name is empty and no resource group ID specified") } - // Valid account ID is required to locate a resource group - // obtain Account ID by account name - it should not be zero on success - - urlValues.Add("includedeleted", "false") - apiResp, err := c.DecortAPICall(ctx, "POST", ResgroupListAPI, urlValues) - if err != nil { - return "", err + listReq := rg.ListRequest{ + IncludeDeleted: false, } - // log.Debugf("%s", apiResp) - log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", ResgroupListAPI) - model := ResgroupListResp{} - err = json.Unmarshal([]byte(apiResp), &model) + model, err := c.CloudBroker().RG().List(ctx, listReq) if err != nil { - return "", err + return nil, err } log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model)) for index, item := range model { // match by RG name & account ID - if item.Name == rgName.(string) && item.AccountID == d.Get("account_id").(int) { + if item.Name == rgName.(string) && item.AccountID == uint64(d.Get("account_id").(int)) { log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d", item.Name, item.ID, item.AccountID, index) - // not all required information is returned by rg/list API, so we need to initiate one more - // call to rg/get to obtain extra data to complete Resource population. - // Namely, we need resource quota settings - reqValues := &url.Values{} - reqValues.Add("rgId", fmt.Sprintf("%d", item.ID)) - apiResp, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, reqValues) + req := rg.GetRequest{ + RGID: item.ID, + } + + apiResp, err := c.CloudBroker().RG().Get(ctx, req) if err != nil { - return "", err + return nil, err } return apiResp, nil } } - return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int)) + return nil, fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int)) } diff --git a/internal/service/cloudbroker/rg/utility_rg_list.go b/internal/service/cloudbroker/rg/utility_rg_list.go index c6067eb..9bb3c07 100644 --- a/internal/service/cloudbroker/rg/utility_rg_list.go +++ b/internal/service/cloudbroker/rg/utility_rg_list.go @@ -33,39 +33,30 @@ package rg import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ResgroupListResp, error) { +func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListRG, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - rgList := ResgroupListResp{} + req := rg.ListRequest{} if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if includedeleted, ok := d.GetOk("includedeleted"); ok { - urlValues.Add("includedeleted", strconv.FormatBool(includedeleted.(bool))) + req.IncludeDeleted = includedeleted.(bool) } log.Debugf("utilityRgListCheckPresence: load rg list") - rgListRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(rgListRaw), &rgList) + rgList, err := c.CloudBroker().RG().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/sep/data_source_sep.go b/internal/service/cloudbroker/sep/data_source_sep.go index 049a773..b3cc897 100644 --- a/internal/service/cloudbroker/sep/data_source_sep.go +++ b/internal/service/cloudbroker/sep/data_source_sep.go @@ -50,13 +50,13 @@ func dataSourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{ id := uuid.New() d.SetId(id.String()) - d.Set("ckey", desSep.Ckey) + d.Set("ckey", desSep.CKey) d.Set("meta", flattens.FlattenMeta(desSep.Meta)) d.Set("consumed_by", desSep.ConsumedBy) - d.Set("desc", desSep.Desc) - d.Set("gid", desSep.Gid) - d.Set("guid", desSep.Guid) - d.Set("sep_id", desSep.Id) + d.Set("desc", desSep.Description) + d.Set("gid", desSep.GID) + d.Set("guid", desSep.GUID) + d.Set("sep_id", desSep.ID) d.Set("milestones", desSep.Milestones) d.Set("name", desSep.Name) d.Set("obj_status", desSep.ObjStatus) diff --git a/internal/service/cloudbroker/sep/data_source_sep_consumption.go b/internal/service/cloudbroker/sep/data_source_sep_consumption.go index ccc6c7c..8167626 100644 --- a/internal/service/cloudbroker/sep/data_source_sep_consumption.go +++ b/internal/service/cloudbroker/sep/data_source_sep_consumption.go @@ -37,9 +37,11 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) +// TODO: how to marshal byPool???? func dataSourceSepConsumptionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { sepCons, err := utilitySepConsumptionCheckPresence(ctx, d, m) if err != nil { @@ -50,7 +52,7 @@ func dataSourceSepConsumptionRead(ctx context.Context, d *schema.ResourceData, m d.Set("type", sepCons.Type) d.Set("total", flattenSepConsumption(sepCons.Total)) - d.Set("by_pool", flattenSepConsumptionPools(sepCons.ByPool)) + // d.Set("by_pool", flattenSepConsumptionPools(sepCons.ByPool)) return nil } @@ -72,7 +74,7 @@ func flattenSepConsumptionPools(mp map[string]SepConsumptionInd) []map[string]in return sh } -func flattenSepConsumption(sc SepConsumptionTotal) []map[string]interface{} { +func flattenSepConsumption(sc sep.Total) []map[string]interface{} { sh := make([]map[string]interface{}, 0) temp := map[string]interface{}{ "capacity_limit": sc.CapacityLimit, diff --git a/internal/service/cloudbroker/sep/data_source_sep_list.go b/internal/service/cloudbroker/sep/data_source_sep_list.go index b240856..4b03f7b 100644 --- a/internal/service/cloudbroker/sep/data_source_sep_list.go +++ b/internal/service/cloudbroker/sep/data_source_sep_list.go @@ -38,22 +38,23 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" ) -func flattenSepList(sl SepList) []map[string]interface{} { +func flattenSepList(sl sep.ListSEP) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, item := range sl { data, _ := json.Marshal(item.Config) temp := map[string]interface{}{ - "ckey": item.Ckey, + "ckey": item.CKey, "meta": flattens.FlattenMeta(item.Meta), "consumed_by": item.ConsumedBy, - "desc": item.Desc, - "gid": item.Gid, - "guid": item.Guid, - "sep_id": item.Id, + "desc": item.Description, + "gid": item.GID, + "guid": item.GUID, + "sep_id": item.ID, "milestones": item.Milestones, "name": item.Name, "obj_status": item.ObjStatus, diff --git a/internal/service/cloudbroker/sep/resource_sep.go b/internal/service/cloudbroker/sep/resource_sep.go index 2be537c..1a445ef 100644 --- a/internal/service/cloudbroker/sep/resource_sep.go +++ b/internal/service/cloudbroker/sep/resource_sep.go @@ -34,78 +34,60 @@ package sep import ( "context" "encoding/json" - "errors" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens" - log "github.com/sirupsen/logrus" ) func resourceSepCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceSepCreate: called for sep %s", d.Get("name").(string)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := sep.CreateRequest{} - urlValues.Add("name", d.Get("name").(string)) - urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int))) - urlValues.Add("sep_type", d.Get("type").(string)) + req.Name = d.Get("name").(string) + req.GID = uint64(d.Get("gid").(int)) + req.SEPType = d.Get("type").(string) if desc, ok := d.GetOk("desc"); ok { - urlValues.Add("description", desc.(string)) + req.Description = desc.(string) } if configString, ok := d.GetOk("config"); ok { - urlValues.Add("config", configString.(string)) + req.Config = configString.(string) } if enable, ok := d.GetOk("enable"); ok { - urlValues.Add("enable", strconv.FormatBool(enable.(bool))) + req.Enable = enable.(bool) } - tstr := d.Get("consumed_by").([]interface{}) - temp := "" - l := len(tstr) - for i, str := range tstr { - s := "\"" + str.(string) + "\"" - if i != (l - 1) { - s += "," - } - temp = temp + s + var consumedNIDs []uint64 + for _, item := range d.Get("consumed_by").([]interface{}) { + consumedNIDs = append(consumedNIDs, uint64(item.(int))) } - temp = "[" + temp + "]" - urlValues.Add("consumer_nids", temp) - - tstr = d.Get("provided_by").([]interface{}) - temp = "" - l = len(tstr) - for i, str := range tstr { - s := "\"" + str.(string) + "\"" - if i != (l - 1) { - s += "," - } - temp = temp + s + + req.ConsumerNIDs = consumedNIDs + + var providerNIDs []uint64 + for _, item := range d.Get("provided_by").([]interface{}) { + providerNIDs = append(providerNIDs, uint64(item.(int))) } - temp = "[" + temp + "]" - urlValues.Add("provider_nids", temp) - sepId, err := c.DecortAPICall(ctx, "POST", sepCreateAPI, urlValues) + req.ProviderNIDs = providerNIDs + + sepId, err := c.CloudBroker().SEP().Create(ctx, req) if err != nil { return diag.FromErr(err) } - d.SetId(sepId) + d.SetId(strconv.FormatUint(sepId, 10)) d.Set("sep_id", sepId) - diagnostics := resourceSepRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceSepRead(ctx, d, m) } func resourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -117,13 +99,13 @@ func resourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{}) return diag.FromErr(err) } - d.Set("ckey", sep.Ckey) + d.Set("ckey", sep.CKey) d.Set("meta", flattens.FlattenMeta(sep.Meta)) d.Set("consumed_by", sep.ConsumedBy) - d.Set("desc", sep.Desc) - d.Set("gid", sep.Gid) - d.Set("guid", sep.Guid) - d.Set("sep_id", sep.Id) + d.Set("desc", sep.Description) + d.Set("gid", sep.GID) + d.Set("guid", sep.GUID) + d.Set("sep_id", sep.ID) d.Set("milestones", sep.Milestones) d.Set("name", sep.Name) d.Set("obj_status", sep.ObjStatus) @@ -148,78 +130,91 @@ func resourceSepDelete(ctx context.Context, d *schema.ResourceData, m interface{ } c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) + req := sep.DeleteRequest{ + SEPID: sepDes.ID, + } - _, err = c.DecortAPICall(ctx, "POST", sepDeleteAPI, urlValues) + _, err = c.CloudBroker().SEP().Delete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } -func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceSepUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceSepEdit: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} if d.HasChange("decommission") { decommission := d.Get("decommission").(bool) if decommission { - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - urlValues.Add("clear_physically", strconv.FormatBool(d.Get("clear_physically").(bool))) - _, err := c.DecortAPICall(ctx, "POST", sepDecommissionAPI, urlValues) + req := sep.DecommissionRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + ClearPhisically: d.Get("clear_physically").(bool), + } + + _, err := c.CloudBroker().SEP().Decommission(ctx, req) if err != nil { return diag.FromErr(err) } } } - urlValues = &url.Values{} if d.HasChange("upd_capacity_limit") { updCapacityLimit := d.Get("upd_capacity_limit").(bool) if updCapacityLimit { - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - _, err := c.DecortAPICall(ctx, "POST", sepUpdateCapacityLimitAPI, urlValues) + req := sep.UpdateCapacityLimitRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + } + + _, err := c.CloudBroker().SEP().UpdateCapacityLimit(ctx, req) if err != nil { return diag.FromErr(err) } } } - urlValues = &url.Values{} if d.HasChange("config") { - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - urlValues.Add("config", d.Get("config").(string)) - _, err := c.DecortAPICall(ctx, "POST", sepConfigValidateAPI, urlValues) + validateReq := sep.ConfigValidateRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + Config: d.Get("config").(string), + } + + insertReq := sep.ConfigInsertRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + Config: d.Get("config").(string), + } + + _, err := c.CloudBroker().SEP().ConfigValidate(ctx, validateReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", sepConfigInsertAPI, urlValues) + _, err = c.CloudBroker().SEP().ConfigInsert(ctx, insertReq) if err != nil { return diag.FromErr(err) } } - urlValues = &url.Values{} if d.HasChange("field_edit") { fieldConfig := d.Get("field_edit").([]interface{}) field := fieldConfig[0].(map[string]interface{}) - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - urlValues.Add("field_name", field["field_name"].(string)) - urlValues.Add("field_value", field["field_value"].(string)) - urlValues.Add("field_type", field["field_type"].(string)) + req := sep.ConfigFieldEditRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + FieldName: field["field_name"].(string), + FieldValue: field["field_value"].(string), + FieldType: field["field_type"].(string), + } - _, err := c.DecortAPICall(ctx, "POST", sepConfigFieldEditAPI, urlValues) + _, err := c.CloudBroker().SEP().ConfigFieldEdit(ctx, req) if err != nil { return diag.FromErr(err) } } - urlValues = &url.Values{} if d.HasChange("enable") { err := resourceSepChangeEnabled(ctx, d, m) if err != nil { @@ -227,7 +222,6 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{}) } } - urlValues = &url.Values{} if d.HasChange("consumed_by") { err := resourceSepUpdateNodes(ctx, d, m) if err != nil { @@ -235,7 +229,6 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{}) } } - urlValues = &url.Values{} if d.HasChange("provided_by") { err := resourceSepUpdateProviders(ctx, d, m) if err != nil { @@ -243,7 +236,6 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{}) } } - urlValues = &url.Values{} if diagnostics := resourceSepRead(ctx, d, m); diagnostics != nil { return diagnostics } @@ -252,42 +244,48 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{}) } func resourceSepChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error { - var api string + sepID := uint64(d.Get("sep_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) if d.Get("enable").(bool) { - api = sepEnableAPI + req := sep.EnableRequest{ + SEPID: sepID, + } + + _, err := c.CloudBroker().SEP().Enable(ctx, req) + if err != nil { + return err + } } else { - api = sepDisableAPI - } - resp, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return err - } - res, err := strconv.ParseBool(resp) - if err != nil { - return err - } - if !res { - return errors.New("Cannot enable/disable") + req := sep.DisableRequest{ + SEPID: sepID, + } + + _, err := c.CloudBroker().SEP().Disable(ctx, req) + if err != nil { + return err + } } + return nil } func resourceSepUpdateNodes(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceSepUpdateNodes: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + delReq := sep.DelConsumerNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + } - t1, t2 := d.GetChange("consumed_by") + addReq := sep.AddConsumerNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + } - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) + toDel := false + + t1, t2 := d.GetChange("consumed_by") consumedIds := make([]interface{}, 0) - temp := "" - api := "" if d1, d2 := t1.([]interface{}), t2.([]interface{}); len(d1) > len(d2) { for _, n := range d2 { @@ -295,25 +293,30 @@ func resourceSepUpdateNodes(ctx context.Context, d *schema.ResourceData, m inter consumedIds = append(consumedIds, n) } } - api = sepDelConsumerNodesAPI + toDel = true } else { consumedIds = d.Get("consumed_by").([]interface{}) - api = sepAddConsumerNodesAPI } - l := len(consumedIds) - for i, consumedId := range consumedIds { - s := strconv.Itoa(consumedId.(int)) - if i != (l - 1) { - s += "," - } - temp = temp + s + var consumerNIDs []uint64 + for _, consumedId := range consumedIds { + consumerNIDs = append(consumerNIDs, uint64(consumedId.(int))) } - temp = "[" + temp + "]" - urlValues.Add("consumer_nids", temp) - _, err := c.DecortAPICall(ctx, "POST", api, urlValues) - if err != nil { - return err + + if toDel { + delReq.ConsumerNIDs = consumerNIDs + + _, err := c.CloudBroker().SEP().DelConsumerNodes(ctx, delReq) + if err != nil { + return err + } + } else { + addReq.ConsumerNIDs = consumerNIDs + + _, err := c.CloudBroker().SEP().AddConsumerNodes(ctx, addReq) + if err != nil { + return err + } } return nil @@ -331,21 +334,17 @@ func findElInt(sl []interface{}, el interface{}) bool { func resourceSepUpdateProviders(ctx context.Context, d *schema.ResourceData, m interface{}) error { log.Debugf("resourceSepUpdateProviders: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - providerIds := d.Get("provided_by").([]interface{}) - temp := "" - l := len(providerIds) - for i, providerId := range providerIds { - s := strconv.Itoa(providerId.(int)) - if i != (l - 1) { - s += "," - } - temp = temp + s + req := sep.AddProviderNodesRequest{ + SEPID: uint64(d.Get("sep_id").(int)), } - temp = "[" + temp + "]" - urlValues.Add("provider_nids", temp) - _, err := c.DecortAPICall(ctx, "POST", sepAddProviderNodesAPI, urlValues) + + var providerNIDs []uint64 + for _, item := range d.Get("provided_by").([]interface{}) { + providerNIDs = append(providerNIDs, uint64(item.(int))) + } + req.ProviderNIDs = providerNIDs + + _, err := c.CloudBroker().SEP().AddProviderNodes(ctx, req) if err != nil { return err } @@ -488,7 +487,7 @@ func ResourceSep() *schema.Resource { CreateContext: resourceSepCreate, ReadContext: resourceSepRead, - UpdateContext: resourceSepEdit, + UpdateContext: resourceSepUpdate, DeleteContext: resourceSepDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudbroker/sep/resource_sep_config.go b/internal/service/cloudbroker/sep/resource_sep_config.go index bf7e64b..fe4ea67 100644 --- a/internal/service/cloudbroker/sep/resource_sep_config.go +++ b/internal/service/cloudbroker/sep/resource_sep_config.go @@ -34,15 +34,14 @@ package sep import ( "context" "encoding/json" - "net/url" - "strconv" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourceSepConfigCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -100,35 +99,43 @@ func resourceSepConfigExists(ctx context.Context, d *schema.ResourceData, m inte return true, nil } -func resourceSepConfigEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceSepConfigUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceSepConfigEdit: called for sep id: %d", d.Get("sep_id").(int)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} if d.HasChange("config") { - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - urlValues.Add("config", d.Get("config").(string)) - _, err := c.DecortAPICall(ctx, "POST", sepConfigValidateAPI, urlValues) + validateReq := sep.ConfigValidateRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + Config: d.Get("config").(string), + } + insertReq := sep.ConfigInsertRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + Config: d.Get("config").(string), + } + + _, err := c.CloudBroker().SEP().ConfigValidate(ctx, validateReq) if err != nil { return diag.FromErr(err) } - _, err = c.DecortAPICall(ctx, "POST", sepConfigInsertAPI, urlValues) + + _, err = c.CloudBroker().SEP().ConfigInsert(ctx, insertReq) if err != nil { return diag.FromErr(err) } } - urlValues = &url.Values{} if d.HasChange("field_edit") { fieldConfig := d.Get("field_edit").([]interface{}) field := fieldConfig[0].(map[string]interface{}) - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - urlValues.Add("field_name", field["field_name"].(string)) - urlValues.Add("field_value", field["field_value"].(string)) - urlValues.Add("field_type", field["field_type"].(string)) + req := sep.ConfigFieldEditRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + FieldName: field["field_name"].(string), + FieldValue: field["field_value"].(string), + FieldType: field["field_type"].(string), + } - _, err := c.DecortAPICall(ctx, "POST", sepConfigFieldEditAPI, urlValues) + _, err := c.CloudBroker().SEP().ConfigFieldEdit(ctx, req) if err != nil { return diag.FromErr(err) } @@ -184,7 +191,7 @@ func ResourceSepConfig() *schema.Resource { CreateContext: resourceSepConfigCreate, ReadContext: resourceSepConfigRead, - UpdateContext: resourceSepConfigEdit, + UpdateContext: resourceSepConfigUpdate, DeleteContext: resourceSepConfigDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudbroker/sep/utility_sep.go b/internal/service/cloudbroker/sep/utility_sep.go index 66f3d63..d9828dc 100644 --- a/internal/service/cloudbroker/sep/utility_sep.go +++ b/internal/service/cloudbroker/sep/utility_sep.go @@ -33,35 +33,28 @@ package sep import ( "context" - "encoding/json" - "net/url" "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilitySepCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Sep, error) { +func utilitySepCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordSEP, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - sep := &Sep{} + req := sep.GetRequest{} if d.Get("sep_id").(int) == 0 { - urlValues.Add("sep_id", d.Id()) + id, _ := strconv.ParseUint(d.Id(), 10, 64) + req.SEPID = id } else { - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) + req.SEPID = uint64(d.Get("sep_id").(int)) } log.Debugf("utilitySepCheckPresence: load sep") - sepRaw, err := c.DecortAPICall(ctx, "POST", sepGetAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(sepRaw), sep) + sep, err := c.CloudBroker().SEP().Get(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/sep/utility_sep_config.go b/internal/service/cloudbroker/sep/utility_sep_config.go index ca9260b..5081371 100644 --- a/internal/service/cloudbroker/sep/utility_sep_config.go +++ b/internal/service/cloudbroker/sep/utility_sep_config.go @@ -33,31 +33,22 @@ package sep import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilitySepConfigCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SepConfig, error) { +func utilitySepConfigCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.SEPConfig, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - sepConfig := SepConfig{} - - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - - log.Debugf("utilitySepConfigCheckPresence: load sep config") - sepConfigRaw, err := c.DecortAPICall(ctx, "POST", sepGetConfigAPI, urlValues) - if err != nil { - return nil, err + req := sep.GetConfigRequest{ + SEPID: uint64(d.Get("sep_id").(int)), } - err = json.Unmarshal([]byte(sepConfigRaw), &sepConfig) + log.Debugf("utilitySepConfigCheckPresence: load sep config") + sepConfig, err := c.CloudBroker().SEP().GetConfig(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/sep/utility_sep_consumption.go b/internal/service/cloudbroker/sep/utility_sep_consumption.go index ad1cc23..36f089c 100644 --- a/internal/service/cloudbroker/sep/utility_sep_consumption.go +++ b/internal/service/cloudbroker/sep/utility_sep_consumption.go @@ -33,28 +33,19 @@ package sep import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilitySepConsumptionCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*SepConsumption, error) { +func utilitySepConsumptionCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordConsumption, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - sepCons := &SepConsumption{} - - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - - sepConsRaw, err := c.DecortAPICall(ctx, "POST", sepConsumptionAPI, urlValues) - if err != nil { - return nil, err + req := sep.ConsumptionRequest{ + SEPID: uint64(d.Get("sep_id").(int)), } - err = json.Unmarshal([]byte(sepConsRaw), sepCons) + sepCons, err := c.CloudBroker().SEP().Consumption(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/sep/utility_sep_disk_list.go b/internal/service/cloudbroker/sep/utility_sep_disk_list.go index 8e30a74..3b328f8 100644 --- a/internal/service/cloudbroker/sep/utility_sep_disk_list.go +++ b/internal/service/cloudbroker/sep/utility_sep_disk_list.go @@ -33,35 +33,26 @@ package sep import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilitySepDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]int, error) { +func utilitySepDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]uint64, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - sepDiskList := SepDiskList{} - - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) + req := sep.DiskListRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + } if poolName, ok := d.GetOk("pool_name"); ok { - urlValues.Add("pool_name", poolName.(string)) + req.PoolName = poolName.(string) } log.Debugf("utilitySepDiskListCheckPresence: load sep") - sepDiskListRaw, err := c.DecortAPICall(ctx, "POST", sepDiskListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(sepDiskListRaw), &sepDiskList) + sepDiskList, err := c.CloudBroker().SEP().DiskList(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/sep/utility_sep_list.go b/internal/service/cloudbroker/sep/utility_sep_list.go index 44da568..462537f 100644 --- a/internal/service/cloudbroker/sep/utility_sep_list.go +++ b/internal/service/cloudbroker/sep/utility_sep_list.go @@ -33,35 +33,27 @@ package sep import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilitySepListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SepList, error) { - sepList := SepList{} +func utilitySepListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (sep.ListSEP, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := sep.ListRequest{} if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilitySepListCheckPresence: load image list") - sepListRaw, err := c.DecortAPICall(ctx, "POST", sepListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(sepListRaw), &sepList) + sepList, err := c.CloudBroker().SEP().List(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/sep/utility_sep_pool.go b/internal/service/cloudbroker/sep/utility_sep_pool.go index 2677bbd..ff80560 100644 --- a/internal/service/cloudbroker/sep/utility_sep_pool.go +++ b/internal/service/cloudbroker/sep/utility_sep_pool.go @@ -33,32 +33,23 @@ package sep import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilitySepPoolCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SepPool, error) { +func utilitySepPoolCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordPool, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - sepPool := SepPool{} - - urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) - urlValues.Add("pool_name", d.Get("pool_name").(string)) - - log.Debugf("utilitySepDesPoolCheckPresence: load sep") - sepPoolRaw, err := c.DecortAPICall(ctx, "POST", sepGetPoolAPI, urlValues) - if err != nil { - return nil, err + req := sep.GetPoolRequest{ + SEPID: uint64(d.Get("sep_id").(int)), + PoolName: d.Get("pool_name").(string), } - err = json.Unmarshal([]byte(sepPoolRaw), &sepPool) + log.Debugf("utilitySepDesPoolCheckPresence: load sep") + sepPool, err := c.CloudBroker().SEP().GetPool(ctx, req) if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/snapshot/data_source_snapshot_list.go b/internal/service/cloudbroker/snapshot/data_source_snapshot_list.go index a2c95fd..48f67bf 100644 --- a/internal/service/cloudbroker/snapshot/data_source_snapshot_list.go +++ b/internal/service/cloudbroker/snapshot/data_source_snapshot_list.go @@ -37,15 +37,16 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenSnapshotList(gl SnapshotList) []map[string]interface{} { +func flattenSnapshotList(gl compute.ListSnapshots) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, item := range gl { temp := map[string]interface{}{ "label": item.Label, - "guid": item.Guid, + "guid": item.GUID, "disks": item.Disks, "timestamp": item.Timestamp, } diff --git a/internal/service/cloudbroker/snapshot/models.go b/internal/service/cloudbroker/snapshot/models.go deleted file mode 100644 index 0d76892..0000000 --- a/internal/service/cloudbroker/snapshot/models.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package snapshot - -type Snapshot struct { - Disks []int `json:"disks"` - Guid string `json:"guid"` - Label string `json:"label"` - Timestamp uint64 `json:"timestamp"` -} - -type SnapshotList []Snapshot diff --git a/internal/service/cloudbroker/snapshot/resource_snapshot.go b/internal/service/cloudbroker/snapshot/resource_snapshot.go index bdce7cf..9eb27a3 100644 --- a/internal/service/cloudbroker/snapshot/resource_snapshot.go +++ b/internal/service/cloudbroker/snapshot/resource_snapshot.go @@ -33,26 +33,26 @@ package snapshot import ( "context" - "net/url" - "strconv" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" ) func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { log.Debugf("resourceSnapshotCreate: called for snapshot %s", d.Get("label").(string)) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("label", d.Get("label").(string)) - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) + req := compute.SnapshotCreateRequest{ + Label: d.Get("label").(string), + ComputeID: uint64(d.Get("compute_id").(int)), + } - snapshotId, err := c.DecortAPICall(ctx, "POST", snapshotCreateAPI, urlValues) + snapshotId, err := c.CloudBroker().Compute().SnapshotCreate(ctx, req) if err != nil { return diag.FromErr(err) } @@ -62,12 +62,7 @@ func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m inter d.SetId(snapshotId) d.Set("guid", snapshotId) - diagnostics := resourceSnapshotRead(ctx, d, m) - if diagnostics != nil { - return diagnostics - } - - return nil + return resourceSnapshotRead(ctx, d, m) } func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -77,7 +72,7 @@ func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interfa } d.Set("timestamp", snapshot.Timestamp) - d.Set("guid", snapshot.Guid) + d.Set("guid", snapshot.GUID) d.Set("disks", snapshot.Disks) d.Set("label", snapshot.Label) @@ -88,20 +83,22 @@ func resourceSnapshotDelete(ctx context.Context, d *schema.ResourceData, m inter log.Debugf("resourceSnapshotDelete: called for %s, id: %s", d.Get("label").(string), d.Id()) c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("label", d.Get("label").(string)) + req := compute.SnapshotDeleteRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Label: d.Get("label").(string), + } - _, err := c.DecortAPICall(ctx, "POST", snapshotDeleteAPI, urlValues) + _, err := c.CloudBroker().Compute().SnapshotDelete(ctx, req) if err != nil { return diag.FromErr(err) } + d.SetId("") return nil } -func resourceSnapshotEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { if d.HasChange("rollback") { if d.Get("rollback").(bool) { err := resourceSnapshotRollback(ctx, d, m) @@ -116,12 +113,12 @@ func resourceSnapshotEdit(ctx context.Context, d *schema.ResourceData, m interfa func resourceSnapshotRollback(ctx context.Context, d *schema.ResourceData, m interface{}) error { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - urlValues.Add("label", d.Get("label").(string)) + req := compute.SnapshotRollbackRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), + Label: d.Get("label").(string), + } - _, err := c.DecortAPICall(ctx, "POST", snapshotRollbackAPI, urlValues) + _, err := c.CloudBroker().Compute().SnapshotRollback(ctx, req) if err != nil { return err } @@ -174,7 +171,7 @@ func ResourceSnapshot() *schema.Resource { CreateContext: resourceSnapshotCreate, ReadContext: resourceSnapshotRead, - UpdateContext: resourceSnapshotEdit, + UpdateContext: resourceSnapshotUpdate, DeleteContext: resourceSnapshotDelete, Importer: &schema.ResourceImporter{ diff --git a/internal/service/cloudbroker/snapshot/utility_snapshot.go b/internal/service/cloudbroker/snapshot/utility_snapshot.go index 663b40b..50a0377 100644 --- a/internal/service/cloudbroker/snapshot/utility_snapshot.go +++ b/internal/service/cloudbroker/snapshot/utility_snapshot.go @@ -36,9 +36,10 @@ import ( "errors" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" ) -func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Snapshot, error) { +func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemSnapshot, error) { snapShotList, err := utilitySnapshotListCheckPresence(ctx, d, m) if err != nil { return nil, err @@ -53,7 +54,7 @@ func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m } for _, s := range snapShotList { - if s.Guid == findId { + if s.GUID == findId { return &s, nil } } diff --git a/internal/service/cloudbroker/snapshot/utility_snapshot_list.go b/internal/service/cloudbroker/snapshot/utility_snapshot_list.go index e3aace0..d970ee9 100644 --- a/internal/service/cloudbroker/snapshot/utility_snapshot_list.go +++ b/internal/service/cloudbroker/snapshot/utility_snapshot_list.go @@ -33,31 +33,20 @@ package snapshot import ( "context" - "encoding/json" - "net/url" - "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilitySnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SnapshotList, error) { +func utilitySnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListSnapshots, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) - - resp, err := c.DecortAPICall(ctx, "POST", snapshotListAPI, urlValues) - if err != nil { - return nil, err + req := compute.SnapshotListRequest{ + ComputeID: uint64(d.Get("compute_id").(int)), } - if resp == "" { - return nil, nil - } - - snapshotList := SnapshotList{} - if err := json.Unmarshal([]byte(resp), &snapshotList); err != nil { - + snapshotList, err := c.CloudBroker().Compute().SnapshotList(ctx, req) + if err != nil { return nil, err } diff --git a/internal/service/cloudbroker/vgpu/data_source_vgpu.go b/internal/service/cloudbroker/vgpu/data_source_vgpu.go index 342e116..bce0430 100644 --- a/internal/service/cloudbroker/vgpu/data_source_vgpu.go +++ b/internal/service/cloudbroker/vgpu/data_source_vgpu.go @@ -46,16 +46,16 @@ func dataSourceVGPURead(ctx context.Context, d *schema.ResourceData, m interface return diag.FromErr(err) } - d.SetId(strconv.Itoa(vgpu.ID)) + d.SetId(strconv.FormatUint(vgpu.ID, 10)) d.Set("vgpu_id", vgpu.ID) d.Set("account_id", vgpu.AccountID) d.Set("mode", vgpu.Mode) - d.Set("pgpu", vgpu.PgpuID) + d.Set("pgpu", vgpu.PGPUID) d.Set("profile_id", vgpu.ProfileID) d.Set("ram", vgpu.RAM) d.Set("status", vgpu.Status) d.Set("type", vgpu.Type) - d.Set("vm_id", vgpu.VmID) + d.Set("vm_id", vgpu.VMID) return nil } diff --git a/internal/service/cloudbroker/vgpu/models.go b/internal/service/cloudbroker/vgpu/models.go deleted file mode 100644 index acd361d..0000000 --- a/internal/service/cloudbroker/vgpu/models.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package vgpu - -type VGPU struct { - AccountID int `json:"accountId"` - ID int `json:"id"` - Mode string `json:"mode"` - PgpuID int `json:"pgpuid"` - ProfileID int `json:"profileId"` - RAM int `json:"ram"` - Status string `json:"status"` - Type string `json:"type"` - VmID int `json:"vmid"` -} diff --git a/internal/service/cloudbroker/vgpu/utility_vgpu.go b/internal/service/cloudbroker/vgpu/utility_vgpu.go index e028bd1..5fb5f5e 100644 --- a/internal/service/cloudbroker/vgpu/utility_vgpu.go +++ b/internal/service/cloudbroker/vgpu/utility_vgpu.go @@ -33,47 +33,38 @@ package vgpu import ( "context" - "encoding/json" - "net/url" "strconv" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vgpu" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" ) -func utilityVGPUCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VGPU, error) { +func utilityVGPUCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vgpu.ItemVGPU, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - urlValues.Add("size", "50") + req := vgpu.ListRequest{ + Size: 50, + } - var vgpuId int + var vgpuId uint64 var err error if vId, ok := d.GetOk("vgpu_id"); ok { - vgpuId = vId.(int) + vgpuId = uint64(vId.(int)) } else { - vgpuId, err = strconv.Atoi(d.Id()) + vgpuId, err = strconv.ParseUint(d.Id(), 10, 64) if err != nil { return nil, err } } for page := 1; ; page++ { - urlValues.Set("page", strconv.Itoa(page)) - resp, err := c.DecortAPICall(ctx, "POST", vgpuListAPI, urlValues) + req.Page = uint64(page) + vgpus, err := c.CloudBroker().VGPU().List(ctx, req) if err != nil { return nil, err } - if resp == "[]" { - return nil, nil - } - - var vgpus []VGPU - if err := json.Unmarshal([]byte(resp), &vgpus); err != nil { - return nil, err - } - for _, vgpu := range vgpus { if vgpu.ID == vgpuId { return &vgpu, nil diff --git a/internal/service/cloudbroker/vins/data_source_vins.go b/internal/service/cloudbroker/vins/data_source_vins.go index 48b7e90..b8929c6 100644 --- a/internal/service/cloudbroker/vins/data_source_vins.go +++ b/internal/service/cloudbroker/vins/data_source_vins.go @@ -33,11 +33,12 @@ package vins import ( "context" - "encoding/json" "fmt" + "reflect" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" // "net/url" @@ -46,44 +47,32 @@ import ( // "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) -// vins_facts is a response string from API vins/get -func flattenVins(d *schema.ResourceData, vins_facts string) diag.Diagnostics { - // NOTE: this function modifies ResourceData argument - as such it should never be called - // from resourceVinsExists(...) method - // log.Debugf("flattenVins: ready to decode response body from API %s", vins_facts) - vinsRecord := VinsRecord{} - err := json.Unmarshal([]byte(vins_facts), &vinsRecord) - if err != nil { - return diag.FromErr(err) - } - +func flattenVins(d *schema.ResourceData, vinsRecord *vins.RecordVINS) diag.Diagnostics { log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d", - vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID) + vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RGID) d.SetId(fmt.Sprintf("%d", vinsRecord.ID)) d.Set("name", vinsRecord.Name) d.Set("account_id", vinsRecord.AccountID) - d.Set("account_name", vinsRecord.AccountName) - d.Set("rg_id", vinsRecord.RgID) - d.Set("description", vinsRecord.Desc) - d.Set("ipcidr", vinsRecord.IPCidr) + // d.Set("account_name", vinsRecord.AccountName) + d.Set("rg_id", vinsRecord.RGID) + d.Set("description", vinsRecord.Description) + d.Set("ipcidr", vinsRecord.Network) noExtNetConnection := true - for _, value := range vinsRecord.VNFs { - if value.Type == "GW" { - log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", value.ID, vinsRecord.ID) - extNetID, idOk := value.Config["ext_net_id"] // NOTE: unknown numbers are unmarshalled to float64. This is by design! - extNetIP, ipOk := value.Config["ext_net_ip"] - if idOk && ipOk { - log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string)) - d.Set("ext_ip_addr", extNetIP.(string)) - d.Set("ext_net_id", int(extNetID.(float64))) - } else { - return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.") - } - noExtNetConnection = false - break + gw := vinsRecord.VNFs.GW + if !reflect.ValueOf(gw).IsZero() { + log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", gw.ID, vinsRecord.ID) + extNetID := gw.Config.ExtNetID + extNetIP := gw.Config.ExtNetIP + if extNetID != 0 && extNetIP != "" { + log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", extNetID, extNetIP) + d.Set("ext_ip_addr", extNetIP) + d.Set("ext_net_id", extNetID) + } else { + return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.") } + noExtNetConnection = false } if noExtNetConnection { @@ -98,10 +87,8 @@ func flattenVins(d *schema.ResourceData, vins_facts string) diag.Diagnostics { func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { vinsFacts, err := utilityVinsCheckPresence(ctx, d, m) - if vinsFacts == "" { - // if empty string is returned from utilityVinsCheckPresence then there is no - // such ViNS and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty in this case + if vinsFacts == nil { + d.SetId("") return diag.FromErr(err) } diff --git a/internal/service/cloudbroker/vins/data_source_vins_list.go b/internal/service/cloudbroker/vins/data_source_vins_list.go index cc6f9a8..b39aadc 100644 --- a/internal/service/cloudbroker/vins/data_source_vins_list.go +++ b/internal/service/cloudbroker/vins/data_source_vins_list.go @@ -37,14 +37,15 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" ) -func flattenVinsList(vl VinsList) []map[string]interface{} { +func flattenVinsList(vl vins.ListVINS) []map[string]interface{} { res := make([]map[string]interface{}, 0) for _, v := range vl { temp := map[string]interface{}{ - "account_id": v.AccountId, + "account_id": v.AccountID, "account_name": v.AccountName, "created_by": v.CreatedBy, "created_time": v.CreatedTime, @@ -59,7 +60,7 @@ func flattenVinsList(vl VinsList) []map[string]interface{} { "status": v.Status, "updated_by": v.UpdatedBy, "updated_time": v.UpdatedTime, - "vxlan_id": v.VXLanID, + "vxlan_id": v.VXLANID, } res = append(res, temp) } diff --git a/internal/service/cloudbroker/vins/models.go b/internal/service/cloudbroker/vins/models.go deleted file mode 100644 index 9854200..0000000 --- a/internal/service/cloudbroker/vins/models.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Authors: -Petr Krutov, -Stanislav Solovev, - -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. -*/ - -/* -Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud -Orchestration Technology) with Terraform by Hashicorp. - -Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort - -Please see README.md to learn where to place source code so that it -builds seamlessly. - -Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki -*/ - -package vins - -type Vins struct { - AccountId int `json:"accountId"` - AccountName string `json:"accountName"` - CreatedBy string `json:"createdBy"` - CreatedTime int `json:"createdTime"` - DeletedBy string `json:"deletedBy"` - DeletedTime int `json:"deletedTime"` - ExternalIP string `json:"externalIP"` - ID int `json:"id"` - Name string `json:"name"` - Network string `json:"network"` - RGID int `json:"rgId"` - RGName string `json:"rgName"` - Status string `json:"status"` - UpdatedBy string `json:"updatedBy"` - UpdatedTime int `json:"updatedTime"` - VXLanID int `json:"vxlanId"` -} - -type VinsList []Vins - -type VinsSearchResp []VinsSearchRecord - -type VnfRecord struct { - ID int `json:"id"` - AccountID int `json:"accountId"` - Type string `json:"type"` // "DHCP", "NAT", "GW" etc - Config map[string]interface{} `json:"config"` // NOTE: VNF specs vary by VNF type -} - -type VnfGwConfigRecord struct { // describes GW VNF config structure inside ViNS, as returned by API vins/get - ExtNetID int `json:"ext_net_id"` - ExtNetIP string `json:"ext_net_ip"` - ExtNetMask int `json:"ext_net_mask"` - DefaultGW string `json:"default_gw"` -} -type VinsRecord struct { // represents part of the response from API vins/get - ID int `json:"id"` - Name string `json:"name"` - IPCidr string `json:"network"` - VxLanID int `json:"vxlanId"` - ExternalIP string `json:"externalIP"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - RgID int `json:"rgid"` - RgName string `json:"rgName"` - VNFs map[string]VnfRecord `json:"vnfs"` - Desc string `json:"desc"` -} - -type VinsSearchRecord struct { - ID int `json:"id"` - Name string `json:"name"` - IPCidr string `json:"network"` - VxLanID int `json:"vxlanId"` - ExternalIP string `json:"externalIP"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` - RgID int `json:"rgId"` - RgName string `json:"rgName"` -} diff --git a/internal/service/cloudbroker/vins/resource_vins.go b/internal/service/cloudbroker/vins/resource_vins.go index a5252d5..30b5b98 100644 --- a/internal/service/cloudbroker/vins/resource_vins.go +++ b/internal/service/cloudbroker/vins/resource_vins.go @@ -33,13 +33,12 @@ package vins import ( "context" - "fmt" - "net/url" "strconv" + log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants" "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" - log "github.com/sirupsen/logrus" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -62,82 +61,78 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d", d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) - apiToCall := VinsCreateInAccountAPI + createInAcc := true c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - - urlValues.Add("name", d.Get("name").(string)) + inAccReq := vins.CreateInAccountRequest{ + Name: d.Get("name").(string), + } + inRGReq := vins.CreateInRGRequest{ + Name: d.Get("name").(string), + } argVal, argSet := d.GetOk("rg_id") if argSet && argVal.(int) > 0 { - apiToCall = VinsCreateInRgAPI - urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int))) + createInAcc = false + inRGReq.RGID = uint64(argVal.(int)) } else { - // RG ID either not set at all or set to 0 - user may want ViNS at account level argVal, argSet = d.GetOk("account_id") if !argSet || argVal.(int) <= 0 { - // No valid Account ID (and no RG ID either) - cannot create ViNS return diag.Errorf("resourceVinsCreate: ViNS name %s - no valid account and/or resource group ID specified", d.Id()) } - urlValues.Add("accountId", fmt.Sprintf("%d", argVal.(int))) + inAccReq.AccountID = uint64(argVal.(int)) } argVal, argSet = d.GetOk("ext_net_id") // NB: even if ext_net_id value is explicitly set to 0, argSet = false anyway if argSet { if argVal.(int) > 0 { - // connect to specific external network - urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int))) - /* - Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform! - - // in case of specific ext net connection user may also want a particular IP address - argVal, argSet = d.GetOk("ext_net_ip") - if argSet && argVal.(string) != "" { - urlValues.Add("extIp", argVal.(string)) - } - */ + inRGReq.ExtNetID = uint64(argVal.(int)) } else { - // ext_net_id is set to a negative value - connect to default external network - // no particular IP address selection in this case - urlValues.Add("extNetId", "0") + inRGReq.ExtNetID = 0 } } argVal, argSet = d.GetOk("ipcidr") if argSet && argVal.(string) != "" { log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string)) - urlValues.Add("ipcidr", argVal.(string)) + inAccReq.IPCIDR = argVal.(string) + inRGReq.IPCIDR = argVal.(string) } argVal, argSet = d.GetOk("description") if argSet { - urlValues.Add("desc", argVal.(string)) + inAccReq.Description = argVal.(string) + inRGReq.Description = argVal.(string) } - apiResp, err := c.DecortAPICall(ctx, "POST", apiToCall, urlValues) - if err != nil { - return diag.FromErr(err) + var vinsID uint64 + if createInAcc { + apiResp, err := c.CloudBroker().VINS().CreateInAccount(ctx, inAccReq) + if err != nil { + return diag.FromErr(err) + } + + vinsID = apiResp + } else { + apiResp, err := c.CloudBroker().VINS().CreateInRG(ctx, inRGReq) + if err != nil { + return diag.FromErr(err) + } + + vinsID = apiResp } - d.SetId(apiResp) // update ID of the resource to tell Terraform that the ViNS resource exists - vinsId, _ := strconv.Atoi(apiResp) + d.SetId(strconv.FormatUint(vinsID, 10)) - log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string)) + log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsID, d.Get("name").(string)) - // We may reuse dataSourceVinsRead here as we maintain similarity - // between ViNS resource and ViNS data source schemas - // ViNS resource read function will also update resource ID on success, so that Terraform - // will know the resource exists (however, we already did it a few lines before) return dataSourceVinsRead(ctx, d, m) } func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { vinsFacts, err := utilityVinsCheckPresence(ctx, d, m) - if vinsFacts == "" { - // if empty string is returned from utilityVinsCheckPresence then there is no - // such ViNS and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty + if vinsFacts == nil { + d.SetId("") return diag.FromErr(err) } @@ -145,40 +140,39 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{} } func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d", d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) c := m.(*controller.ControllerCfg) + vinsID, _ := strconv.ParseUint(d.Id(), 10, 64) - // 1. Handle external network connection change oldExtNetId, newExtNedId := d.GetChange("ext_net_id") if oldExtNetId.(int) != newExtNedId.(int) { log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int)) - extnetParams := &url.Values{} - extnetParams.Add("vinsId", d.Id()) - if oldExtNetId.(int) > 0 { // there was preexisting external net connection - disconnect ViNS - _, err := c.DecortAPICall(ctx, "POST", VinsExtNetDisconnectAPI, extnetParams) + req := vins.ExtNetDisconnectRequest{VINSID: vinsID} + + _, err := c.CloudBroker().VINS().ExtNetDisconnect(ctx, req) if err != nil { return diag.FromErr(err) } } if newExtNedId.(int) > 0 { - // new external network connection requested - connect ViNS - extnetParams.Add("netId", fmt.Sprintf("%d", newExtNedId.(int))) - _, err := c.DecortAPICall(ctx, "POST", VinsExtNetConnectAPI, extnetParams) + req := vins.ExtNetConnectRequest{ + VINSID: vinsID, + NetID: uint64(newExtNedId.(int)), + } + + _, err := c.CloudBroker().VINS().ExtNetConnect(ctx, req) if err != nil { return diag.FromErr(err) } } } - // we may reuse dataSourceVinsRead here as we maintain similarity - // between Compute resource and Compute data source schemas return dataSourceVinsRead(ctx, d, m) } @@ -187,7 +181,7 @@ func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) vinsFacts, err := utilityVinsCheckPresence(ctx, d, m) - if vinsFacts == "" { + if vinsFacts == nil { if err != nil { return diag.FromErr(err) } @@ -196,13 +190,14 @@ func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface return nil } - params := &url.Values{} - params.Add("vinsId", d.Id()) - params.Add("force", "1") // disconnect all computes before deleting ViNS - params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin - c := m.(*controller.ControllerCfg) - _, err = c.DecortAPICall(ctx, "POST", VinsDeleteAPI, params) + req := vins.DeleteRequest{ + VINSID: vinsFacts.ID, + Force: true, + Permanently: true, + } + + _, err = c.CloudBroker().VINS().Delete(ctx, req) if err != nil { return diag.FromErr(err) } diff --git a/internal/service/cloudbroker/vins/utility_vins.go b/internal/service/cloudbroker/vins/utility_vins.go index 945812d..898411c 100644 --- a/internal/service/cloudbroker/vins/utility_vins.go +++ b/internal/service/cloudbroker/vins/utility_vins.go @@ -33,44 +33,25 @@ package vins import ( "context" - "encoding/json" "fmt" - "net/url" "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -// On success this function returns a string, as returned by API vins/get, which could be unmarshalled -// into VinsGetResp structure -func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) { - // This function tries to locate ViNS by one of the following algorithms depending - // on the parameters passed: - // - if resource group ID is specified -> it looks for a ViNS at the RG level - // - if account ID is specifeid -> it looks for a ViNS at the account level - // - // If succeeded, it returns non empty string that contains JSON formatted facts about the - // ViNS as returned by vins/get API call. - // Otherwise it returns empty string and a meaningful error. - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for the Terraform resource Exists method. - // - +func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.RecordVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} - // make it possible to use "read" & "check presence" functions with ViNS ID set so - // that Import of ViNS resource is possible idSet := false - theId, err := strconv.Atoi(d.Id()) - if err != nil || theId <= 0 { + vinsID, err := strconv.ParseUint(d.Id(), 10, 64) + if err != nil || vinsID <= 0 { vinsId, argSet := d.GetOk("vins_id") // NB: vins_id is NOT present in vinsResource schema! if argSet { - theId = vinsId.(int) + vinsID = uint64(vinsId.(int)) idSet = true } } else { @@ -78,76 +59,65 @@ func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m int } if idSet { - // ViNS ID is specified, try to get compute instance straight by this ID - log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", theId) - urlValues.Add("vinsId", fmt.Sprintf("%d", theId)) - vinsFacts, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues) + log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", vinsID) + req := vins.GetRequest{VINSID: vinsID} + + vinsFacts, err := c.CloudBroker().VINS().Get(ctx, req) if err != nil { - return "", err + return nil, err } + return vinsFacts, nil } - // ID was not set in the schema upon entering this function - work through ViNS name - // and Account / RG ID - vinsName, argSet := d.GetOk("name") if !argSet { - // if ViNS name is not set. then we cannot locate ViNS - return "", fmt.Errorf("Cannot check ViNS presence if ViNS name is empty") + return nil, fmt.Errorf("Cannot check ViNS presence if ViNS name is empty") + } + req := vins.SearchRequest{ + Name: vinsName.(string), + ShowAll: false, } - urlValues.Add("name", vinsName.(string)) - urlValues.Add("show_all", "false") log.Debugf("utilityVinsCheckPresence: preparing to locate ViNS name %s", vinsName.(string)) rgId, rgSet := d.GetOk("rg_id") if rgSet { log.Debugf("utilityVinsCheckPresence: limiting ViNS search to RG ID %d", rgId.(int)) - urlValues.Add("rgId", fmt.Sprintf("%d", rgId.(int))) + req.RGID = uint64(rgId.(int)) } accountId, accountSet := d.GetOk("account_id") if accountSet { log.Debugf("utilityVinsCheckPresence: limiting ViNS search to Account ID %d", accountId.(int)) - urlValues.Add("accountId", fmt.Sprintf("%d", accountId.(int))) - } - - apiResp, err := c.DecortAPICall(ctx, "POST", VinsSearchAPI, urlValues) - if err != nil { - return "", err + req.AccountID = uint64(accountId.(int)) } - // log.Debugf("%s", apiResp) - // log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI) - model := VinsSearchResp{} - err = json.Unmarshal([]byte(apiResp), &model) + vinsList, err := c.CloudBroker().VINS().Search(ctx, req) if err != nil { - return "", err + return nil, err } - log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(model)) - for index, item := range model { + log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(vinsList)) + for index, item := range vinsList { if item.Name == vinsName.(string) { - if (accountSet && item.AccountID != accountId.(int)) || - (rgSet && item.RgID != rgId.(int)) { - // double check that account ID and Rg ID match, if set in the schema + if (accountSet && item.AccountID != uint64(accountId.(int))) || + (rgSet && item.RGID != uint64(rgId.(int))) { continue } log.Debugf("utilityVinsCheckPresence: match ViNS name %s / ID %d, account ID %d, RG ID %d at index %d", - item.Name, item.ID, item.AccountID, item.RgID, index) + item.Name, item.ID, item.AccountID, item.RGID, index) + + req := vins.GetRequest{VINSID: item.ID} - // element returned by API vins/search does not contain all information we may need to - // manage ViNS, so we have to get detailed info by calling API vins/get - rqValues := &url.Values{} - rqValues.Add("vinsId", fmt.Sprintf("%d", item.ID)) - vinsGetResp, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, rqValues) + vinsGetResp, err := c.CloudBroker().VINS().Get(ctx, req) if err != nil { - return "", err + return nil, err } + return vinsGetResp, nil } } - return "", fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string)) + return nil, fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string)) } diff --git a/internal/service/cloudbroker/vins/utility_vins_list.go b/internal/service/cloudbroker/vins/utility_vins_list.go index 4472bc0..b938e0a 100644 --- a/internal/service/cloudbroker/vins/utility_vins_list.go +++ b/internal/service/cloudbroker/vins/utility_vins_list.go @@ -33,38 +33,27 @@ package vins import ( "context" - "encoding/json" - "net/url" - "strconv" - "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" log "github.com/sirupsen/logrus" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins" + "repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VinsList, error) { - vinsList := VinsList{} +func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListVINS, error) { c := m.(*controller.ControllerCfg) - urlValues := &url.Values{} + req := vins.ListRequest{} - if includeDeleted, ok := d.GetOk("include_deleted"); ok { - urlValues.Add("includeDeleted", strconv.FormatBool(includeDeleted.(bool))) - } if page, ok := d.GetOk("page"); ok { - urlValues.Add("page", strconv.Itoa(page.(int))) + req.Page = uint64(page.(int)) } if size, ok := d.GetOk("size"); ok { - urlValues.Add("size", strconv.Itoa(size.(int))) + req.Size = uint64(size.(int)) } log.Debugf("utilityVinsListCheckPresence") - vinsListRaw, err := c.DecortAPICall(ctx, "POST", VinsListAPI, urlValues) - if err != nil { - return nil, err - } - - err = json.Unmarshal([]byte(vinsListRaw), &vinsList) + vinsList, err := c.CloudBroker().VINS().List(ctx, req) if err != nil { return nil, err }