diff --git a/go.mod b/go.mod index 543c54912..b20a68422 100644 --- a/go.mod +++ b/go.mod @@ -3,61 +3,61 @@ module github.com/terraform-provider-openstack/terraform-provider-openstack go 1.17 require ( - github.com/gophercloud/gophercloud v0.24.0 + github.com/gophercloud/gophercloud v0.25.0 github.com/gophercloud/utils v0.0.0-20220307143606-8e7800759d16 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.16.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.17.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/stretchr/testify v1.7.1 - golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect + github.com/stretchr/testify v1.7.2 gopkg.in/yaml.v2 v2.4.0 ) require ( - github.com/agext/levenshtein v1.2.2 // indirect + github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.7.0 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.8 // indirect - github.com/hashicorp/errwrap v1.0.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 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect - github.com/hashicorp/go-hclog v1.2.0 // indirect + github.com/hashicorp/go-hclog v1.2.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.4.3 // indirect + github.com/hashicorp/go-plugin v1.4.4 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/go-version v1.4.0 // indirect + github.com/hashicorp/go-version v1.5.0 // indirect github.com/hashicorp/hc-install v0.3.2 // indirect github.com/hashicorp/hcl/v2 v2.12.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.16.1 // indirect - github.com/hashicorp/terraform-json v0.13.0 // indirect - github.com/hashicorp/terraform-plugin-go v0.9.0 // indirect - github.com/hashicorp/terraform-plugin-log v0.4.0 // indirect - github.com/hashicorp/terraform-registry-address v0.0.0-20210412075316-9b2996cce896 // indirect + github.com/hashicorp/terraform-json v0.14.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.9.1 // indirect + github.com/hashicorp/terraform-plugin-log v0.4.1 // indirect + github.com/hashicorp/terraform-registry-address v0.0.0-20220510144317-d78f4a47ae27 // indirect github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect - github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.10 // indirect + github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/oklog/run v1.0.0 // indirect + github.com/oklog/run v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect - github.com/vmihailenco/tagparser v0.1.1 // indirect + github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/zclconf/go-cty v1.10.0 // indirect - golang.org/x/crypto v0.0.0-20211202192323-5770296d904e // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/text v0.3.6 // indirect - google.golang.org/appengine v1.6.6 // indirect - google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect - google.golang.org/grpc v1.45.0 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/net v0.0.0-20220615171555-694bf12d69de // indirect + golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20220615141314-f1464d18c36b // indirect + google.golang.org/grpc v1.47.0 // indirect google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index be1faaaa8..7b8b32406 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= 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-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= @@ -30,8 +32,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk 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-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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= @@ -43,10 +45,12 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF 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.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +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 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= 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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -91,13 +95,15 @@ 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/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gophercloud/gophercloud v0.20.0/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4= -github.com/gophercloud/gophercloud v0.24.0 h1:jDsIMGJ1KZpAjYfQgGI2coNQj5Q83oPzuiGJRFWgMzw= -github.com/gophercloud/gophercloud v0.24.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= +github.com/gophercloud/gophercloud v0.25.0 h1:C3Oae7y0fUVQGSsBrb3zliAjdX+riCSEh4lNMejFNI4= +github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= github.com/gophercloud/utils v0.0.0-20220307143606-8e7800759d16 h1:slt/exMiitZNY+5OrKJ6ZvSogqN+SyzeYzAtyI6db9A= github.com/gophercloud/utils v0.0.0-20220307143606-8e7800759d16/go.mod h1:qOGlfG6OIJ193/c3Xt/XjOfHataNZdQcVgiu93LxBUM= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= 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= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -109,18 +115,21 @@ github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBM github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +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-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.3 h1:DXmvivbWD5qdiBts9TpBC7BYL1Aia5sxbRgQB+v6UZM= -github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= +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-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E= +github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hc-install v0.3.1/go.mod h1:3LCdWcCDS1gaHC9mhHCGbkYfoY6vdsKohGjugbZdZak= github.com/hashicorp/hc-install v0.3.2 h1:oiQdJZvXmkNcRcEOOfM5n+VTsvNjWQeOjfAoO6dKSH8= github.com/hashicorp/hc-install v0.3.2/go.mod h1:xMG6Tr8Fw1WFjlxH0A9v61cW15pFwgEGqEz0V4jisHs= @@ -130,22 +139,28 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-exec v0.16.1 h1:NAwZFJW2L2SaCBVZoVaH8LPImLOGbPLkSHy0IYbs2uE= github.com/hashicorp/terraform-exec v0.16.1/go.mod h1:aj0lVshy8l+MHhFNoijNHtqTJQI3Xlowv5EOsEaGO7M= -github.com/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY= github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk= -github.com/hashicorp/terraform-plugin-go v0.9.0 h1:FvLY/3z4SNVatPZdoFcyrlNbCar+WyyOTv5X4Tp+WZc= -github.com/hashicorp/terraform-plugin-go v0.9.0/go.mod h1:EawBkgjBWNf7jiKnVoyDyF39OSV+u6KUX+Y73EPj3oM= -github.com/hashicorp/terraform-plugin-log v0.3.0/go.mod h1:EjueSP/HjlyFAsDqt+okpCPjkT4NDynAe32AeDC4vps= +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-go v0.9.1 h1:vXdHaQ6aqL+OF076nMSBV+JKPdmXlzG5mzVDD04WyPs= +github.com/hashicorp/terraform-plugin-go v0.9.1/go.mod h1:ItjVSlQs70otlzcCwlPcU8FRXLdO973oYFRZwAOxy8M= github.com/hashicorp/terraform-plugin-log v0.4.0 h1:F3eVnm8r2EfQCe2k9blPIiF/r2TT01SHijXnS7bujvc= github.com/hashicorp/terraform-plugin-log v0.4.0/go.mod h1:9KclxdunFownr4pIm1jdmwKRmE4d6HVG2c9XDq47rpg= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.16.0 h1:9fjPgCenJqnbjo95SDcbJ+YdLyEC1N35cwKWcRWhJTQ= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.16.0/go.mod h1:hLa0sTiySU/AWEgV2GxJh0/pQIqcCmm30IPja9N9lTg= +github.com/hashicorp/terraform-plugin-log v0.4.1 h1:xpbmVhvuU3mgHzLetOmx9pkOL2rmgpu302XxddON6eo= +github.com/hashicorp/terraform-plugin-log v0.4.1/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.17.0 h1:Qr5fWNg1SPSfCRMtou67Y6Kcy9UnMYRNlIJTKRuUvXU= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.17.0/go.mod h1:b+LFg8WpYgFgvEBP/6Htk5H9/pJp1V1E8NJAekfH2Ws= github.com/hashicorp/terraform-registry-address v0.0.0-20210412075316-9b2996cce896 h1:1FGtlkJw87UsTMg5s8jrekrHmUPUJaMcu6ELiVhQrNw= github.com/hashicorp/terraform-registry-address v0.0.0-20210412075316-9b2996cce896/go.mod h1:bzBPnUIkI0RxauU8Dqo+2KrZZ28Cf48s8V6IHt3p4co= +github.com/hashicorp/terraform-registry-address v0.0.0-20220510144317-d78f4a47ae27 h1:IOawOnLgKntezAV3oJs17rkhXha+h0EF5OMjb2KFlYc= +github.com/hashicorp/terraform-registry-address v0.0.0-20220510144317-d78f4a47ae27/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI= 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-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= 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.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -169,9 +184,15 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +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-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +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/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -182,6 +203,8 @@ github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= 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= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -191,6 +214,8 @@ github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= 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= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -211,8 +236,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -220,6 +245,8 @@ github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvC 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= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -242,6 +269,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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= @@ -261,11 +290,15 @@ golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 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-20220615171555-694bf12d69de h1:ogOG2+P6LjO2j55AkRScrkB2BFpd+Z8TY2wcM0Z3MGo= +golang.org/x/net v0.0.0-20220615171555-694bf12d69de/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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= @@ -284,16 +317,25 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -303,6 +345,8 @@ 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.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/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/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= @@ -319,6 +363,8 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 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-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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= @@ -326,6 +372,8 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG 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-20220615141314-f1464d18c36b h1:2LXbOcxY7BehyA9yu5hxYzaY67bLaJQhBX9O1zxxVis= +google.golang.org/genproto v0.0.0-20220615141314-f1464d18c36b/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -334,8 +382,10 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/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.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= 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= @@ -366,7 +416,8 @@ 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.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= diff --git a/openstack/containerinfra_shared_v1.go b/openstack/containerinfra_shared_v1.go index 9fef21a33..080ccb133 100644 --- a/openstack/containerinfra_shared_v1.go +++ b/openstack/containerinfra_shared_v1.go @@ -19,11 +19,15 @@ import ( "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/certificates" "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters" "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates" + "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/nodegroups" ) const ( rsaPrivateKeyBlockType = "RSA PRIVATE KEY" certificateRequestBlockType = "CERTIFICATE REQUEST" + + containerInfraV1NodeGroupMinMicroversion = "1.9" + containerInfraV1ZeroNodeCountMicroversion = "1.10" ) func expandContainerInfraV1LabelsMap(v map[string]interface{}) (map[string]string, error) { @@ -55,6 +59,21 @@ func expandContainerInfraV1LabelsString(v map[string]interface{}) (string, error return formattedLabels, nil } +func containerInfraV1GetLabelsMerged(labelsAdded map[string]string, labelsSkipped map[string]string, labelsOverridden map[string]string, labels map[string]string) map[string]string { + m := make(map[string]string) + for key, val := range labelsAdded { + m[key] = val + } + for key, val := range labelsSkipped { + m[key] = val + } + for key := range labelsOverridden { + // We have to get the actual value here, not the one overridden + m[key] = labels[key] + } + return m +} + func containerInfraClusterTemplateV1AppendUpdateOpts(updateOpts []clustertemplates.UpdateOptsBuilder, attribute, value string) []clustertemplates.UpdateOptsBuilder { if value == "" { updateOpts = append(updateOpts, clustertemplates.UpdateOpts{ @@ -71,6 +90,22 @@ func containerInfraClusterTemplateV1AppendUpdateOpts(updateOpts []clustertemplat return updateOpts } +func containerInfraNodeGroupV1AppendUpdateOpts(updateOpts []nodegroups.UpdateOptsBuilder, attribute, value string) []nodegroups.UpdateOptsBuilder { + if value == "" { + updateOpts = append(updateOpts, nodegroups.UpdateOpts{ + Op: nodegroups.RemoveOp, + Path: strings.Join([]string{"/", attribute}, ""), + }) + } else { + updateOpts = append(updateOpts, nodegroups.UpdateOpts{ + Op: nodegroups.ReplaceOp, + Path: strings.Join([]string{"/", attribute}, ""), + Value: value, + }) + } + return updateOpts +} + // ContainerInfraClusterV1StateRefreshFunc returns a resource.StateRefreshFunc // that is used to watch a container infra Cluster. func containerInfraClusterV1StateRefreshFunc(client *gophercloud.ServiceClient, clusterID string) resource.StateRefreshFunc { @@ -101,6 +136,36 @@ func containerInfraClusterV1StateRefreshFunc(client *gophercloud.ServiceClient, } } +// ContainerInfraNodeGroupV1StateRefreshFunc returns a resource.StateRefreshFunc +// that is used to watch a container infra NodeGroup. +func containerInfraNodeGroupV1StateRefreshFunc(client *gophercloud.ServiceClient, clusterID string, nodeGroupID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + nodeGroup, err := nodegroups.Get(client, clusterID, nodeGroupID).Extract() + if err != nil { + if _, ok := err.(gophercloud.ErrDefault404); ok { + return nodeGroup, "DELETE_COMPLETE", nil + } + return nil, "", err + } + + errorStatuses := []string{ + "CREATE_FAILED", + "UPDATE_FAILED", + "DELETE_FAILED", + "RESUME_FAILED", + "ROLLBACK_FAILED", + } + for _, errorStatus := range errorStatuses { + if nodeGroup.Status == errorStatus { + err = fmt.Errorf("openstack_containerinfra_nodegroup_v1 is in an error state: %s", nodeGroup.StatusReason) + return nodeGroup, nodeGroup.Status, err + } + } + + return nodeGroup, nodeGroup.Status, nil + } +} + // containerInfraClusterV1Flavor will determine the flavor for a container infra // cluster based on either what was set in the configuration or environment // variable. diff --git a/openstack/data_source_openstack_containerinfra_cluster_v1_test.go b/openstack/data_source_openstack_containerinfra_cluster_v1_test.go index 19ba38a9a..769fdb1f7 100644 --- a/openstack/data_source_openstack_containerinfra_cluster_v1_test.go +++ b/openstack/data_source_openstack_containerinfra_cluster_v1_test.go @@ -12,7 +12,6 @@ import ( func TestAccContainerInfraV1ClusterDataSource_basic(t *testing.T) { resourceName := "openstack_containerinfra_cluster_v1.cluster_1" clusterName := acctest.RandomWithPrefix("tf-acc-cluster") - imageName := acctest.RandomWithPrefix("tf-acc-image") keypairName := acctest.RandomWithPrefix("tf-acc-keypair") clusterTemplateName := acctest.RandomWithPrefix("tf-acc-clustertemplate") @@ -25,11 +24,11 @@ func TestAccContainerInfraV1ClusterDataSource_basic(t *testing.T) { CheckDestroy: testAccCheckContainerInfraV1ClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccContainerInfraV1ClusterBasic(imageName, keypairName, clusterTemplateName, clusterName), + Config: testAccContainerInfraV1ClusterBasic(keypairName, clusterTemplateName, clusterName), }, { Config: testAccContainerInfraV1ClusterDataSourceBasic( - testAccContainerInfraV1ClusterBasic(imageName, keypairName, clusterTemplateName, clusterName), + testAccContainerInfraV1ClusterBasic(keypairName, clusterTemplateName, clusterName), ), Check: resource.ComposeTestCheckFunc( testAccCheckContainerInfraV1ClusterDataSourceID(resourceName), diff --git a/openstack/data_source_openstack_containerinfra_nodegroup_v1.go b/openstack/data_source_openstack_containerinfra_nodegroup_v1.go new file mode 100644 index 000000000..ab7f06005 --- /dev/null +++ b/openstack/data_source_openstack_containerinfra_nodegroup_v1.go @@ -0,0 +1,133 @@ +package openstack + +import ( + "context" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/nodegroups" +) + +func dataSourceContainerInfraNodeGroupV1() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceContainerInfraNodeGroupRead, + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "cluster_id": { + Type: schema.TypeString, + Required: true, + }, + + "name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + }, + + "project_id": { + Type: schema.TypeString, + Computed: true, + }, + + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + + "docker_volume_size": { + Type: schema.TypeInt, + Computed: true, + }, + + "labels": { + Type: schema.TypeMap, + Computed: true, + }, + + "role": { + Type: schema.TypeString, + Computed: true, + }, + + "node_count": { + Type: schema.TypeInt, + Computed: true, + }, + + "min_node_count": { + Type: schema.TypeInt, + Computed: true, + }, + + "max_node_count": { + Type: schema.TypeInt, + Computed: true, + }, + + "image": { + Type: schema.TypeString, + Computed: true, + }, + + "flavor": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceContainerInfraNodeGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*Config) + containerInfraClient, err := config.ContainerInfraV1Client(GetRegion(d, config)) + if err != nil { + return diag.Errorf("Error creating OpenStack container infra client: %s", err) + } + + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + + clusterID := d.Get("cluster_id").(string) + name := d.Get("name").(string) + nodeGroup, err := nodegroups.Get(containerInfraClient, clusterID, name).Extract() + if err != nil { + return diag.Errorf("Error getting openstack_containerinfra_nodegroup_v1 %s: %s", name, err) + } + + d.SetId(nodeGroup.UUID) + + d.Set("project_id", nodeGroup.ProjectID) + d.Set("docker_volume_size", nodeGroup.DockerVolumeSize) + d.Set("role", nodeGroup.Role) + d.Set("node_count", nodeGroup.NodeCount) + d.Set("min_node_count", nodeGroup.MinNodeCount) + d.Set("max_node_count", nodeGroup.MaxNodeCount) + d.Set("image", nodeGroup.ImageID) + d.Set("flavor", nodeGroup.FlavorID) + + if err := d.Set("labels", nodeGroup.Labels); err != nil { + log.Printf("[DEBUG] Unable to set labels for openstack_containerinfra_nodegroup_v1 %s: %s", nodeGroup.UUID, err) + } + if err := d.Set("created_at", nodeGroup.CreatedAt.Format(time.RFC3339)); err != nil { + log.Printf("[DEBUG] Unable to set created_at for openstack_containerinfra_nodegroup_v1 %s: %s", nodeGroup.UUID, err) + } + if err := d.Set("updated_at", nodeGroup.UpdatedAt.Format(time.RFC3339)); err != nil { + log.Printf("[DEBUG] Unable to set updated_at for openstack_containerinfra_nodegroup_v1 %s: %s", nodeGroup.UUID, err) + } + + d.Set("region", GetRegion(d, config)) + + return nil +} diff --git a/openstack/data_source_openstack_containerinfra_nodegroup_v1_test.go b/openstack/data_source_openstack_containerinfra_nodegroup_v1_test.go new file mode 100644 index 000000000..c2c034c95 --- /dev/null +++ b/openstack/data_source_openstack_containerinfra_nodegroup_v1_test.go @@ -0,0 +1,68 @@ +package openstack + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccContainerInfraV1NodeGroupDataSource_basic(t *testing.T) { + resourceName := "openstack_containerinfra_nodegroup_v1.nodegroup_1" + nodeGroupName := acctest.RandomWithPrefix("tf-acc-nodegroup") + clusterName := acctest.RandomWithPrefix("tf-acc-cluster") + keypairName := acctest.RandomWithPrefix("tf-acc-keypair") + clusterTemplateName := acctest.RandomWithPrefix("tf-acc-clustertemplate") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheckNonAdminOnly(t) + testAccPreCheckContainerInfra(t) + }, + ProviderFactories: testAccProviders, + CheckDestroy: testAccCheckContainerInfraV1ClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContainerInfraV1NodeGroupUpdate(keypairName, clusterTemplateName, clusterName, nodeGroupName, 1), + }, + { + Config: testAccContainerInfraV1NodeGroupDataSourceBasic( + testAccContainerInfraV1NodeGroupUpdate(keypairName, clusterTemplateName, clusterName, nodeGroupName, 1), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckContainerInfraV1NodeGroupDataSourceID(resourceName), + resource.TestCheckResourceAttr(resourceName, "name", nodeGroupName), + resource.TestCheckResourceAttr(resourceName, "node_count", "1"), + ), + }, + }, + }) +} + +func testAccCheckContainerInfraV1NodeGroupDataSourceID(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ct, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find cluster data source: %s", n) + } + + if ct.Primary.ID == "" { + return fmt.Errorf("Cluster data source ID is not set") + } + + return nil + } +} + +func testAccContainerInfraV1NodeGroupDataSourceBasic(nodeGroupResource string) string { + return fmt.Sprintf(` +%s + +data "openstack_containerinfra_nodegroup_v1" "nodegroup_1" { + cluster_id = "${openstack_containerinfra_cluster_v1.cluster_1.name}" + name = "${openstack_containerinfra_nodegroup_v1.nodegroup_1.name}" +} +`, nodeGroupResource) +} diff --git a/openstack/import_openstack_containerinfra_cluster_v1_test.go b/openstack/import_openstack_containerinfra_cluster_v1_test.go index 26c8b01e3..4adc33e8c 100644 --- a/openstack/import_openstack_containerinfra_cluster_v1_test.go +++ b/openstack/import_openstack_containerinfra_cluster_v1_test.go @@ -10,7 +10,6 @@ import ( func TestAccContainerInfraV1ClusterImport_basic(t *testing.T) { resourceName := "openstack_containerinfra_cluster_v1.cluster_1" clusterName := acctest.RandomWithPrefix("tf-acc-cluster") - imageName := acctest.RandomWithPrefix("tf-acc-image") keypairName := acctest.RandomWithPrefix("tf-acc-keypair") clusterTemplateName := acctest.RandomWithPrefix("tf-acc-clustertemplate") @@ -24,7 +23,7 @@ func TestAccContainerInfraV1ClusterImport_basic(t *testing.T) { CheckDestroy: testAccCheckContainerInfraV1ClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccContainerInfraV1ClusterBasic(imageName, keypairName, clusterTemplateName, clusterName), + Config: testAccContainerInfraV1ClusterBasic(keypairName, clusterTemplateName, clusterName), }, { ResourceName: resourceName, diff --git a/openstack/import_openstack_containerinfra_nodegroup_v1_test.go b/openstack/import_openstack_containerinfra_nodegroup_v1_test.go new file mode 100644 index 000000000..f073add38 --- /dev/null +++ b/openstack/import_openstack_containerinfra_nodegroup_v1_test.go @@ -0,0 +1,37 @@ +package openstack + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccContainerInfraV1NodeGroupImport_basic(t *testing.T) { + resourceName := "openstack_containerinfra_nodegroup_v1.nodegroup_1" + clusterName := acctest.RandomWithPrefix("tf-acc-cluster") + keypairName := acctest.RandomWithPrefix("tf-acc-keypair") + clusterTemplateName := acctest.RandomWithPrefix("tf-acc-clustertemplate") + nodeGroupName := acctest.RandomWithPrefix("tf-acc-cluster") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckNonAdminOnly(t) + testAccPreCheckContainerInfra(t) + }, + ProviderFactories: testAccProviders, + CheckDestroy: testAccCheckContainerInfraV1NodeGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContainerInfraV1NodeGroupUpdate(keypairName, clusterTemplateName, clusterName, nodeGroupName, 1), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"cluster_id"}, + }, + }, + }) +} diff --git a/openstack/provider.go b/openstack/provider.go index 6e6f718c7..5cd9c9cbe 100644 --- a/openstack/provider.go +++ b/openstack/provider.go @@ -270,6 +270,7 @@ func Provider() *schema.Provider { "openstack_compute_hypervisor_v2": dataSourceComputeHypervisorV2(), "openstack_compute_keypair_v2": dataSourceComputeKeypairV2(), "openstack_compute_quotaset_v2": dataSourceComputeQuotasetV2(), + "openstack_containerinfra_nodegroup_v1": dataSourceContainerInfraNodeGroupV1(), "openstack_containerinfra_clustertemplate_v1": dataSourceContainerInfraClusterTemplateV1(), "openstack_containerinfra_cluster_v1": dataSourceContainerInfraCluster(), "openstack_dns_zone_v2": dataSourceDNSZoneV2(), @@ -331,6 +332,7 @@ func Provider() *schema.Provider { "openstack_compute_floatingip_v2": resourceComputeFloatingIPV2(), "openstack_compute_floatingip_associate_v2": resourceComputeFloatingIPAssociateV2(), "openstack_compute_volume_attach_v2": resourceComputeVolumeAttachV2(), + "openstack_containerinfra_nodegroup_v1": resourceContainerInfraNodeGroupV1(), "openstack_containerinfra_clustertemplate_v1": resourceContainerInfraClusterTemplateV1(), "openstack_containerinfra_cluster_v1": resourceContainerInfraClusterV1(), "openstack_db_instance_v1": resourceDatabaseInstanceV1(), diff --git a/openstack/provider_test.go b/openstack/provider_test.go index ea79ca491..b064f4c24 100644 --- a/openstack/provider_test.go +++ b/openstack/provider_test.go @@ -27,6 +27,7 @@ var ( osImageID = os.Getenv("OS_IMAGE_ID") osImageName = os.Getenv("OS_IMAGE_NAME") osMagnumFlavor = os.Getenv("OS_MAGNUM_FLAVOR") + osMagnumImage = os.Getenv("OS_MAGNUM_IMAGE") osNetworkID = os.Getenv("OS_NETWORK_ID") osPoolName = os.Getenv("OS_POOL_NAME") osRegionName = os.Getenv("OS_REGION_NAME") diff --git a/openstack/resource_openstack_containerinfra_cluster_v1.go b/openstack/resource_openstack_containerinfra_cluster_v1.go index 712422204..153f1af3c 100644 --- a/openstack/resource_openstack_containerinfra_cluster_v1.go +++ b/openstack/resource_openstack_containerinfra_cluster_v1.go @@ -2,6 +2,7 @@ package openstack import ( "context" + "fmt" "log" "strconv" "strings" @@ -11,7 +12,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters" + "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/nodegroups" ) func resourceContainerInfraClusterV1() *schema.Resource { @@ -160,7 +163,7 @@ func resourceContainerInfraClusterV1() *schema.Resource { Type: schema.TypeInt, Optional: true, ForceNew: false, - Computed: true, + Default: 1, }, "master_addresses": { @@ -274,8 +277,11 @@ func resourceContainerInfraClusterV1Create(ctx context.Context, d *schema.Resour } nodeCount := d.Get("node_count").(int) - if nodeCount > 0 { + if nodeCount >= 0 { createOpts.NodeCount = &nodeCount + if nodeCount == 0 { + containerInfraClient.Microversion = containerInfraV1ZeroNodeCountMicroversion + } } mergeLabels := d.Get("merge_labels").(bool) @@ -310,6 +316,29 @@ func resourceContainerInfraClusterV1Create(ctx context.Context, d *schema.Resour return resourceContainerInfraClusterV1Read(ctx, d, meta) } +func getDefaultNodegroupNodeCount(containerInfraClient *gophercloud.ServiceClient, clusterID string) (int, error) { + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + listOpts := nodegroups.ListOpts{} + + allPages, err := nodegroups.List(containerInfraClient, clusterID, listOpts).AllPages() + if err != nil { + return 0, err + } + + ngs, err := nodegroups.ExtractNodeGroups(allPages) + if err != nil { + return 0, err + } + + for _, ng := range ngs { + if ng.IsDefault && ng.Role != "master" { + return ng.NodeCount, nil + } + } + + return 0, fmt.Errorf("Default worker nodegroup not found") +} + func resourceContainerInfraClusterV1Read(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { config := meta.(*Config) containerInfraClient, err := config.ContainerInfraV1Client(GetRegion(d, config)) @@ -324,10 +353,21 @@ func resourceContainerInfraClusterV1Read(_ context.Context, d *schema.ResourceDa log.Printf("[DEBUG] Retrieved openstack_containerinfra_cluster_v1 %s: %#v", d.Id(), s) - if err := d.Set("labels", s.Labels); err != nil { + labels := s.Labels + if d.Get("merge_labels").(bool) { + labels = containerInfraV1GetLabelsMerged(s.LabelsAdded, s.LabelsSkipped, s.LabelsOverridden, s.Labels) + } + if err := d.Set("labels", labels); err != nil { return diag.Errorf("Unable to set openstack_containerinfra_cluster_v1 labels: %s", err) } + nodeCount, err := getDefaultNodegroupNodeCount(containerInfraClient, d.Id()) + if err != nil { + log.Printf("[DEBUG] Can't retrieve node_count of the default worker node group %s: %s", d.Id(), err) + + nodeCount = s.NodeCount + } + d.Set("name", s.Name) d.Set("api_address", s.APIAddress) d.Set("coe_version", s.COEVersion) @@ -340,7 +380,7 @@ func resourceContainerInfraClusterV1Read(_ context.Context, d *schema.ResourceDa d.Set("master_flavor", s.MasterFlavorID) d.Set("keypair", s.KeyPair) d.Set("master_count", s.MasterCount) - d.Set("node_count", s.NodeCount) + d.Set("node_count", nodeCount) d.Set("master_addresses", s.MasterAddresses) d.Set("node_addresses", s.NodeAddresses) d.Set("stack_id", s.StackID) diff --git a/openstack/resource_openstack_containerinfra_cluster_v1_test.go b/openstack/resource_openstack_containerinfra_cluster_v1_test.go index 98cba0dcb..1b7393e14 100644 --- a/openstack/resource_openstack_containerinfra_cluster_v1_test.go +++ b/openstack/resource_openstack_containerinfra_cluster_v1_test.go @@ -17,7 +17,6 @@ func TestAccContainerInfraV1Cluster_basic(t *testing.T) { resourceName := "openstack_containerinfra_cluster_v1.cluster_1" clusterName := acctest.RandomWithPrefix("tf-acc-cluster") - imageName := acctest.RandomWithPrefix("tf-acc-image") keypairName := acctest.RandomWithPrefix("tf-acc-keypair") clusterTemplateName := acctest.RandomWithPrefix("tf-acc-clustertemplate") @@ -31,7 +30,7 @@ func TestAccContainerInfraV1Cluster_basic(t *testing.T) { CheckDestroy: testAccCheckContainerInfraV1ClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccContainerInfraV1ClusterBasic(imageName, keypairName, clusterTemplateName, clusterName), + Config: testAccContainerInfraV1ClusterBasic(keypairName, clusterTemplateName, clusterName), Check: resource.ComposeTestCheckFunc( testAccCheckContainerInfraV1ClusterExists(resourceName, &cluster), resource.TestCheckResourceAttr(resourceName, "name", clusterName), @@ -42,7 +41,7 @@ func TestAccContainerInfraV1Cluster_basic(t *testing.T) { ), }, { - Config: testAccContainerInfraV1ClusterUpdate(imageName, keypairName, clusterTemplateName, clusterName), + Config: testAccContainerInfraV1ClusterUpdate(keypairName, clusterTemplateName, clusterName), Check: resource.ComposeTestCheckFunc( testAccCheckContainerInfraV1ClusterExists(resourceName, &cluster), resource.TestCheckResourceAttr(resourceName, "name", clusterName), @@ -109,25 +108,15 @@ func testAccCheckContainerInfraV1ClusterDestroy(s *terraform.State) error { return nil } -func testAccContainerInfraV1ClusterBasic(imageName, keypairName, clusterTemplateName, clusterName string) string { +func testAccContainerInfraV1ClusterBasic(keypairName, clusterTemplateName, clusterName string) string { return fmt.Sprintf(` -resource "openstack_images_image_v2" "image_1" { - name = "%s" - image_source_url = "https://dl.fedoraproject.org/pub/fedora/linux/releases/27/CloudImages/x86_64/images/Fedora-Atomic-27-1.6.x86_64.qcow2" - container_format = "bare" - disk_format = "qcow2" - properties = { - os_distro = "fedora-atomic" - } -} - resource "openstack_compute_keypair_v2" "keypair_1" { name = "%s" } resource "openstack_containerinfra_clustertemplate_v1" "clustertemplate_1" { name = "%s" - image = "${openstack_images_image_v2.image_1.name}" + image = "%s" coe = "kubernetes" master_flavor = "%s" flavor = "%s" @@ -148,28 +137,18 @@ resource "openstack_containerinfra_cluster_v1" "cluster_1" { node_count = 1 keypair = "${openstack_compute_keypair_v2.keypair_1.name}" } -`, imageName, keypairName, clusterTemplateName, osMagnumFlavor, osMagnumFlavor, osExtGwID, clusterName) +`, keypairName, clusterTemplateName, osMagnumImage, osMagnumFlavor, osMagnumFlavor, osExtGwID, clusterName) } -func testAccContainerInfraV1ClusterUpdate(imageName, keypairName, clusterTemplateName, clusterName string) string { +func testAccContainerInfraV1ClusterUpdate(keypairName, clusterTemplateName, clusterName string) string { return fmt.Sprintf(` -resource "openstack_images_image_v2" "image_1" { - name = "%s" - image_source_url = "https://dl.fedoraproject.org/pub/fedora/linux/releases/27/CloudImages/x86_64/images/Fedora-Atomic-27-1.6.x86_64.qcow2" - container_format = "bare" - disk_format = "qcow2" - properties = { - os_distro = "fedora-atomic" - } -} - resource "openstack_compute_keypair_v2" "keypair_1" { name = "%s" } resource "openstack_containerinfra_clustertemplate_v1" "clustertemplate_1" { name = "%s" - image = "${openstack_images_image_v2.image_1.name}" + image = "%s" coe = "kubernetes" master_flavor = "%s" flavor = "%s" @@ -188,5 +167,5 @@ resource "openstack_containerinfra_cluster_v1" "cluster_1" { node_count = 2 keypair = "${openstack_compute_keypair_v2.keypair_1.name}" } -`, imageName, keypairName, clusterTemplateName, osMagnumFlavor, osMagnumFlavor, osExtGwID, clusterName) +`, keypairName, clusterTemplateName, osMagnumImage, osMagnumFlavor, osMagnumFlavor, osExtGwID, clusterName) } diff --git a/openstack/resource_openstack_containerinfra_clustertemplate_v1.go b/openstack/resource_openstack_containerinfra_clustertemplate_v1.go index 0412fa75a..6c98a08b1 100644 --- a/openstack/resource_openstack_containerinfra_clustertemplate_v1.go +++ b/openstack/resource_openstack_containerinfra_clustertemplate_v1.go @@ -330,12 +330,12 @@ func resourceContainerInfraClusterTemplateV1Read(_ context.Context, d *schema.Re d.Set("external_network_id", s.ExternalNetworkID) d.Set("fixed_network", s.FixedNetwork) d.Set("fixed_subnet", s.FixedSubnet) - d.Set("flavor_id", s.FlavorID) - d.Set("master_flavor_id", s.MasterFlavorID) + d.Set("flavor", s.FlavorID) + d.Set("master_flavor", s.MasterFlavorID) d.Set("floating_ip_enabled", s.FloatingIPEnabled) d.Set("http_proxy", s.HTTPProxy) d.Set("https_proxy", s.HTTPSProxy) - d.Set("image_id", s.ImageID) + d.Set("image", s.ImageID) d.Set("insecure_registry", s.InsecureRegistry) d.Set("keypair_id", s.KeyPairID) d.Set("master_lb_enabled", s.MasterLBEnabled) diff --git a/openstack/resource_openstack_containerinfra_nodegroup_v1.go b/openstack/resource_openstack_containerinfra_nodegroup_v1.go new file mode 100644 index 000000000..cff5cf1ef --- /dev/null +++ b/openstack/resource_openstack_containerinfra_nodegroup_v1.go @@ -0,0 +1,372 @@ +package openstack + +import ( + "context" + "fmt" + "log" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters" + "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/nodegroups" +) + +func resourceContainerInfraNodeGroupV1() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceContainerInfraNodeGroupV1Create, + ReadContext: resourceContainerInfraNodeGroupV1Read, + UpdateContext: resourceContainerInfraNodeGroupV1Update, + DeleteContext: resourceContainerInfraNodeGroupV1Delete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(60 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + + "cluster_id": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "project_id": { + Type: schema.TypeString, + ForceNew: true, + Computed: true, + }, + + "created_at": { + Type: schema.TypeString, + ForceNew: false, + Computed: true, + }, + + "updated_at": { + Type: schema.TypeString, + ForceNew: false, + Computed: true, + }, + + "docker_volume_size": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Computed: true, + }, + + "labels": { + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + Computed: true, + }, + + "merge_labels": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + }, + + "role": { + Type: schema.TypeString, + ForceNew: true, + Computed: true, + }, + + "node_count": { + Type: schema.TypeInt, + Optional: true, + Default: 1, + }, + + "min_node_count": { + Type: schema.TypeInt, + Optional: true, + ForceNew: false, + Computed: true, + }, + + "max_node_count": { + Type: schema.TypeInt, + Optional: true, + ForceNew: false, + Computed: true, + }, + + "image_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + + "flavor_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + }, + } +} + +func resourceContainerInfraNodeGroupV1Create(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*Config) + containerInfraClient, err := config.ContainerInfraV1Client(GetRegion(d, config)) + if err != nil { + return diag.Errorf("Error creating OpenStack container infra client: %s", err) + } + + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + + // Get and check labels map. + rawLabels := d.Get("labels").(map[string]interface{}) + labels, err := expandContainerInfraV1LabelsMap(rawLabels) + if err != nil { + return diag.FromErr(err) + } + + createOpts := nodegroups.CreateOpts{ + Name: d.Get("name").(string), + Labels: labels, + MinNodeCount: d.Get("min_node_count").(int), + Role: d.Get("role").(string), + ImageID: d.Get("image_id").(string), + FlavorID: d.Get("flavor_id").(string), + } + + // Set int parameters that will be passed by reference. + dockerVolumeSize := d.Get("docker_volume_size").(int) + if dockerVolumeSize > 0 { + createOpts.DockerVolumeSize = &dockerVolumeSize + } + nodeCount := d.Get("node_count").(int) + if nodeCount >= 0 { + createOpts.NodeCount = &nodeCount + if nodeCount == 0 { + containerInfraClient.Microversion = containerInfraV1ZeroNodeCountMicroversion + } + } + maxNodeCount := d.Get("max_node_count").(int) + if maxNodeCount > 0 { + createOpts.MaxNodeCount = &maxNodeCount + } + + mergeLabels := d.Get("merge_labels").(bool) + if mergeLabels { + createOpts.MergeLabels = &mergeLabels + } + + log.Printf("[DEBUG] openstack_containerinfra_nodegroup_v1 create options: %#v", createOpts) + + clusterID := d.Get("cluster_id").(string) + nodeGroup, err := nodegroups.Create(containerInfraClient, clusterID, createOpts).Extract() + if err != nil { + return diag.Errorf("Error creating openstack_containerinfra_nodegroup_v1: %s", err) + } + + id := fmt.Sprintf("%s/%s", clusterID, nodeGroup.UUID) + d.SetId(id) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"CREATE_IN_PROGRESS"}, + Target: []string{"CREATE_COMPLETE"}, + Refresh: containerInfraNodeGroupV1StateRefreshFunc(containerInfraClient, clusterID, nodeGroup.UUID), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 1 * time.Minute, + PollInterval: 20 * time.Second, + } + _, err = stateConf.WaitForStateContext(ctx) + if err != nil { + return diag.Errorf( + "Error waiting for openstack_containerinfra_nodegroup_v1 %s to become ready: %s", nodeGroup.UUID, err) + } + + log.Printf("[DEBUG] Created openstack_containerinfra_nodegroup_v1 %s", nodeGroup.UUID) + + return resourceContainerInfraNodeGroupV1Read(ctx, d, meta) +} + +func resourceContainerInfraNodeGroupV1Read(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*Config) + containerInfraClient, err := config.ContainerInfraV1Client(GetRegion(d, config)) + if err != nil { + return diag.Errorf("Error creating OpenStack container infra client: %s", err) + } + + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + + clusterID, nodeGroupID, err := parseNodeGroupID(d.Id()) + if err != nil { + return diag.FromErr(CheckDeleted(d, err, "Error parsing ID of openstack_containerinfra_nodegroup_v1")) + } + + nodeGroup, err := nodegroups.Get(containerInfraClient, clusterID, nodeGroupID).Extract() + if err != nil { + return diag.FromErr(CheckDeleted(d, err, "Error retrieving openstack_containerinfra_nodegroup_v1")) + } + + log.Printf("[DEBUG] Retrieved openstack_containerinfra_nodegroup_v1 %s: %#v", d.Id(), nodeGroup) + + labels := nodeGroup.Labels + if d.Get("merge_labels").(bool) { + labels = containerInfraV1GetLabelsMerged(nodeGroup.LabelsAdded, nodeGroup.LabelsSkipped, nodeGroup.LabelsOverridden, nodeGroup.Labels) + } + if err := d.Set("labels", labels); err != nil { + return diag.Errorf("Unable to set openstack_containerinfra_nodegroup_v1 labels: %s", err) + } + + d.Set("cluster_id", clusterID) + d.Set("region", GetRegion(d, config)) + d.Set("name", nodeGroup.Name) + d.Set("project_id", nodeGroup.ProjectID) + d.Set("role", nodeGroup.Role) + d.Set("node_count", nodeGroup.NodeCount) + d.Set("min_node_count", nodeGroup.NodeCount) + d.Set("max_node_count", nodeGroup.NodeCount) + d.Set("image_id", nodeGroup.ImageID) + d.Set("flavor_id", nodeGroup.FlavorID) + + if err := d.Set("created_at", nodeGroup.CreatedAt.Format(time.RFC3339)); err != nil { + log.Printf("[DEBUG] Unable to set openstack_containerinfra_nodegroup_v1 created_at: %s", err) + } + if err := d.Set("updated_at", nodeGroup.UpdatedAt.Format(time.RFC3339)); err != nil { + log.Printf("[DEBUG] Unable to set openstack_containerinfra_nodegroup_v1 updated_at: %s", err) + } + + return nil +} + +func resourceContainerInfraNodeGroupV1Update(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*Config) + containerInfraClient, err := config.ContainerInfraV1Client(GetRegion(d, config)) + if err != nil { + return diag.Errorf("Error creating OpenStack container infra client: %s", err) + } + + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + + clusterID, nodeGroupID, err := parseNodeGroupID(d.Id()) + if err != nil { + return diag.FromErr(CheckDeleted(d, err, "Error parsing ID of openstack_containerinfra_nodegroup_v1")) + } + + updateOpts := []nodegroups.UpdateOptsBuilder{} + + if d.HasChange("min_node_count") { + v := d.Get("min_node_count").(int) + minNodeCount := strconv.Itoa(v) + updateOpts = containerInfraNodeGroupV1AppendUpdateOpts( + updateOpts, "min_node_count", minNodeCount) + } + + if d.HasChange("max_node_count") { + v := d.Get("max_node_count").(int) + maxNodeCount := strconv.Itoa(v) + updateOpts = containerInfraNodeGroupV1AppendUpdateOpts( + updateOpts, "max_node_count", maxNodeCount) + } + + if len(updateOpts) > 0 { + log.Printf( + "[DEBUG] Updating openstack_containerinfra_nodegroup_v1 %s with options: %#v", d.Id(), updateOpts) + + _, err = nodegroups.Update(containerInfraClient, clusterID, nodeGroupID, updateOpts).Extract() + if err != nil { + return diag.Errorf("Error updating openstack_containerinfra_nodegroup_v1 %s: %s", d.Id(), err) + } + } + + if d.HasChange("node_count") { + v := d.Get("node_count").(int) + var resizeOpts = clusters.ResizeOpts{ + NodeCount: &v, + NodeGroup: nodeGroupID, + } + _, err = clusters.Resize(containerInfraClient, clusterID, resizeOpts).Extract() + if err != nil { + return diag.Errorf("Error resizing openstack_containerinfra_nodegroup_v1 %s: %s", d.Id(), err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"UPDATE_IN_PROGRESS"}, + Target: []string{"UPDATE_COMPLETE"}, + Refresh: containerInfraNodeGroupV1StateRefreshFunc(containerInfraClient, clusterID, nodeGroupID), + Timeout: d.Timeout(schema.TimeoutUpdate), + Delay: 1 * time.Minute, + PollInterval: 20 * time.Second, + } + _, err = stateConf.WaitForStateContext(ctx) + if err != nil { + return diag.Errorf( + "Error waiting for openstack_containerinfra_node_group_v1 %s to become updated: %s", d.Id(), err) + } + } + return resourceContainerInfraNodeGroupV1Read(ctx, d, meta) +} + +func resourceContainerInfraNodeGroupV1Delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*Config) + containerInfraClient, err := config.ContainerInfraV1Client(GetRegion(d, config)) + if err != nil { + return diag.Errorf("Error creating OpenStack container infra client: %s", err) + } + + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + + clusterID, nodeGroupID, err := parseNodeGroupID(d.Id()) + if err != nil { + return diag.FromErr(CheckDeleted(d, err, "Error parsing ID of openstack_containerinfra_nodegroup_v1")) + } + + if err := nodegroups.Delete(containerInfraClient, clusterID, nodeGroupID).ExtractErr(); err != nil { + return diag.FromErr(CheckDeleted(d, err, "Error deleting openstack_containerinfra_nodegroup_v1")) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"DELETE_IN_PROGRESS"}, + Target: []string{"DELETE_COMPLETE"}, + Refresh: containerInfraNodeGroupV1StateRefreshFunc(containerInfraClient, clusterID, nodeGroupID), + Timeout: d.Timeout(schema.TimeoutDelete), + Delay: 30 * time.Second, + PollInterval: 10 * time.Second, + } + _, err = stateConf.WaitForStateContext(ctx) + if err != nil { + return diag.Errorf( + "Error waiting for openstack_containerinfra_nodegroup_v1 %s to become deleted: %s", d.Id(), err) + } + + return nil +} + +func parseNodeGroupID(id string) (string, string, error) { + idParts := strings.Split(id, "/") + if len(idParts) < 2 { + return "", "", fmt.Errorf("Unable to determine nodegroup ID %s", id) + } + + return idParts[0], idParts[1], nil +} diff --git a/openstack/resource_openstack_containerinfra_nodegroup_v1_test.go b/openstack/resource_openstack_containerinfra_nodegroup_v1_test.go new file mode 100644 index 000000000..d752e6700 --- /dev/null +++ b/openstack/resource_openstack_containerinfra_nodegroup_v1_test.go @@ -0,0 +1,143 @@ +package openstack + +import ( + "fmt" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/nodegroups" +) + +func TestAccContainerInfraV1NodeGroup_basic(t *testing.T) { + var nodeGroup nodegroups.NodeGroup + + resourceName := "openstack_containerinfra_nodegroup_v1.nodegroup_1" + clusterName := acctest.RandomWithPrefix("tf-acc-cluster") + keypairName := acctest.RandomWithPrefix("tf-acc-keypair") + clusterTemplateName := acctest.RandomWithPrefix("tf-acc-clustertemplate") + nodeGroupName := acctest.RandomWithPrefix("tf-acc-nodegroup") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckNonAdminOnly(t) + testAccPreCheckContainerInfra(t) + }, + ProviderFactories: testAccProviders, + CheckDestroy: testAccCheckContainerInfraV1NodeGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContainerInfraV1NodeGroupUpdate(keypairName, clusterTemplateName, clusterName, nodeGroupName, 1), + Check: resource.ComposeTestCheckFunc( + testAccCheckContainerInfraV1NodeGroupExists(resourceName, &nodeGroup), + resource.TestCheckResourceAttr(resourceName, "name", nodeGroupName), + resource.TestCheckResourceAttr(resourceName, "node_count", strconv.Itoa(1)), + ), + }, + { + Config: testAccContainerInfraV1NodeGroupUpdate(keypairName, clusterTemplateName, clusterName, nodeGroupName, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckContainerInfraV1NodeGroupExists(resourceName, &nodeGroup), + resource.TestCheckResourceAttr(resourceName, "name", nodeGroupName), + resource.TestCheckResourceAttr(resourceName, "node_count", strconv.Itoa(2)), + ), + }, + }, + }) +} + +func testAccCheckContainerInfraV1NodeGroupExists(n string, nodeGroup *nodegroups.NodeGroup) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + containerInfraClient, err := config.ContainerInfraV1Client(osRegionName) + if err != nil { + return fmt.Errorf("Error creating OpenStack container infra client: %s", err) + } + + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + clusterID, nodeGroupID, err := parseNodeGroupID(rs.Primary.ID) + if err != nil { + return err + } + found, err := nodegroups.Get(containerInfraClient, clusterID, nodeGroupID).Extract() + if err != nil { + return err + } + + if found.UUID != nodeGroupID { + return fmt.Errorf("Nodegroup not found") + } + + *nodeGroup = *found + + return nil + } +} + +func testAccCheckContainerInfraV1NodeGroupDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + containerInfraClient, err := config.ContainerInfraV1Client(osRegionName) + if err != nil { + return fmt.Errorf("Error creating OpenStack container infra client: %s", err) + } + + containerInfraClient.Microversion = containerInfraV1NodeGroupMinMicroversion + + for _, rs := range s.RootModule().Resources { + if rs.Type != "openstack_containerinfra_nodegroup_v1" { + continue + } + clusterID, nodeGroupID, err := parseVolumeTypeAccessID(rs.Primary.ID) + if err != nil { + return err + } + + _, err = nodegroups.Get(containerInfraClient, clusterID, nodeGroupID).Extract() + if err == nil { + return fmt.Errorf("node group still exists") + } + } + + return nil +} +func testAccContainerInfraV1NodeGroupUpdate(keypairName, clusterTemplateName, clusterName string, nodeGroupName string, nodeCount int) string { + return fmt.Sprintf(` +resource "openstack_compute_keypair_v2" "keypair_1" { + name = "%s" +} + +resource "openstack_containerinfra_clustertemplate_v1" "clustertemplate_1" { + name = "%s" + image = "%s" + coe = "kubernetes" + http_proxy = "127.0.0.1:8801" +} + +resource "openstack_containerinfra_cluster_v1" "cluster_1" { + name = "%s" + cluster_template_id = "${openstack_containerinfra_clustertemplate_v1.clustertemplate_1.id}" + master_count = 1 + node_count = 1 + keypair = "${openstack_compute_keypair_v2.keypair_1.name}" +} + +resource "openstack_containerinfra_nodegroup_v1" "nodegroup_1" { + name = "%s" + cluster_id = "${openstack_containerinfra_cluster_v1.cluster_1.id}" + node_count = %d +} +`, keypairName, clusterTemplateName, osMagnumImage, clusterName, nodeGroupName, nodeCount) +} diff --git a/website/docs/d/containerinfra_nodegroup_v1.html.markdown b/website/docs/d/containerinfra_nodegroup_v1.html.markdown new file mode 100644 index 000000000..f995b5b3e --- /dev/null +++ b/website/docs/d/containerinfra_nodegroup_v1.html.markdown @@ -0,0 +1,64 @@ +--- +layout: "openstack" +page_title: "OpenStack: openstack_containerinfra_nodegroup_v1" +sidebar_current: "docs-openstack-datasource-containerinfra-nodegroup-v1" +description: |- + Get information on an OpenStack Magnum node group. +--- + +# openstack\_containerinfra\_nodegroup\_v1 + +Use this data source to get information of an available OpenStack Magnum node group. + +## Example Usage + +```hcl +data "openstack_containerinfra_nodegroup_v1" "nodegroup_1" { + cluster_id = "cluster_1" + name = "nodegroup_1" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional) The region in which to obtain the V1 Container Infra + client. + If omitted, the `region` argument of the provider is used. + +* `cluster_id` - (Required) The name of the OpenStack Magnum cluster. + +* `name` - (Required) The name of the node group. + +## Attributes Reference + +`id` is set to the ID of the found node group. In addition, the following +attributes are exported: + +* `name` - See Argument Reference above. + +* `region` - See Argument Reference above. + +* `project_id` - The project of the node group. + +* `created_at` - The time at which the node group was created. + +* `updated_at` - The time at which the node group was updated. + +* `docker_volume_size` - The size (in GB) of the Docker volume. + +* `labels` - The list of key value pairs representing additional properties of + the node group. + +* `role` - The role of the node group. + +* `node_count` - The number of nodes for the node group. + +* `min_node_count` - The minimum number of nodes for the node group. + +* `max_node_count` - The maximum number of nodes for the node group. + +* `image` - The reference to an image that is used for nodes of the node group. + +* `flavor` - The flavor for the nodes of the node group. diff --git a/website/docs/r/containerinfra_nodegroup_v1.html.markdown b/website/docs/r/containerinfra_nodegroup_v1.html.markdown new file mode 100644 index 000000000..2bafa2942 --- /dev/null +++ b/website/docs/r/containerinfra_nodegroup_v1.html.markdown @@ -0,0 +1,99 @@ +--- +layout: "openstack" +page_title: "OpenStack: openstack_containerinfra_cluster_v1" +sidebar_current: "docs-openstack-resource-containerinfra-cluster-v1" +description: |- + Manages a V1 Magnum node group resource within OpenStack. +--- + +# openstack\_containerinfra\_nodegroup\_v1 + +Manages a V1 Magnum node group resource within OpenStack. + +## Example Usage + +### Create a Cluster + +```hcl +resource "openstack_containerinfra_nodegroup_v1" "nodegroup_1" { + name = "nodegroup_1" + cluster_id = "b9a45c5c-cd03-4958-82aa-b80bf93cb922" + node_count = 5 +} +``` + +## Argument reference + +The following arguments are supported: + +* `region` - (Optional) The region in which to obtain the V1 Container Infra + client. A Container Infra client is needed to create a cluster. If omitted, + the `region` argument of the provider is used. Changing this creates a new + node group. + +* `name` - (Required) The name of the node group. Changing this creates a new + node group. + +* `project_id` - (Optional) The project of the node group. Required if admin + wants to create a cluster in another project. Changing this creates a new + node group. + +* `cluster_id` - (Required) The UUID of the V1 Container Infra cluster. + Changing this creates a new node group. + +* `docker_volume_size` - (Optional) The size (in GB) of the Docker volume. + Changing this creates a new node group. + +* `image` - (Required) The reference to an image that is used for nodes of the + node group. Can be set via the `OS_MAGNUM_IMAGE` environment variable. + Changing this updates the image attribute of the existing node group. + +* `flavor` - (Optional) The flavor for the nodes of the node group. Can be set + via the `OS_MAGNUM_FLAVOR` environment variable. Changing this creates a new + node group. + +* `labels` - (Optional) The list of key value pairs representing additional + properties of the node group. Changing this creates a new node group. + +* `merge_labels` - (Optional) Indicates whether the provided labels should be + merged with cluster labels. Changing this creates a new nodegroup. + +* `node_count` - (Optional) The number of nodes for the node group. Changing + this update the number of nodes of the node group. + +* `min_node_count` - (Optional) The minimum number of nodes for the node group. + Changing this update the minimum number of nodes of the node group. + +* `max_node_count` - (Optional) The maximum number of nodes for the node group. + Changing this update the maximum number of nodes of the node group. + +* `role` - (Optional) The role of nodes in the node group. Changing this + creates a new node group. + + +## Attributes reference + +The following attributes are exported: + +* `region` - See Argument Reference above. +* `name` - See Argument Reference above. +* `project_id` - See Argument Reference above. +* `created_at` - The time at which cluster was created. +* `updated_at` - The time at which cluster was created. +* `docker_volume_size` - See Argument Reference above. +* `role` - See Argument Reference above. +* `image` - See Argument Reference above. +* `flavor` - See Argument Reference above. +* `labels` - See Argument Reference above. +* `node_count` - See Argument Reference above. +* `min_node_count` - See Argument Reference above. +* `max_node_count` - See Argument Reference above. +* `role` - See Argument Reference above. + +## Import + +Node groups can be imported using the `id`, e.g. + +``` +$ terraform import openstack_containerinfra_nodegroup_v1.nodegroup_1 ce0f9463-dd25-474b-9fe8-94de63e5e42b +```