From a5ff4ce5ce584a5fbfc3510a721ba8ba71b13ca4 Mon Sep 17 00:00:00 2001 From: pavel <36902936+pavel-github@users.noreply.github.com> Date: Sun, 24 Nov 2024 22:43:40 +0100 Subject: [PATCH] feat(resource/xelon_ssh_key): migrate ssh key resource to framework --- docs/index.md | 2 +- docs/resources/ssh_key.md | 11 +- go.mod | 49 ++-- go.sum | 94 +++--- internal/provider/provider.go | 6 +- internal/provider/resource_xelon_ssh_key.go | 209 +++++++++++++ internal/xelon/provider.go | 6 +- internal/xelon/resource_xelon_ssh_key.go | 272 ++++++++--------- internal/xelon/resource_xelon_ssh_key_test.go | 274 +++++++++--------- 9 files changed, 568 insertions(+), 355 deletions(-) create mode 100644 internal/provider/resource_xelon_ssh_key.go diff --git a/docs/index.md b/docs/index.md index 4434e6c..ad05d8a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -41,6 +41,6 @@ provider "xelon" { ### Optional -- `base_url` (String) The base URL endpoint for Xelon HQ. Default is `https://hq.xelon.ch/api/service/`. Alternatively, can be configured using the `XELON_BASE_URL` environment variable. +- `base_url` (String) The base URL endpoint for Xelon HQ. Default is `https://hq.xelon.ch/api/v2/`. Alternatively, can be configured using the `XELON_BASE_URL` environment variable. - `client_id` (String) The client ID for IP ranges. Alternatively, can be configured using the `XELON_CLIENT_ID` environment variable. - `token` (String) The Xelon access token. Alternatively, can be configured using the `XELON_TOKEN` environment variable. diff --git a/docs/resources/ssh_key.md b/docs/resources/ssh_key.md index f8b9b51..2a717e0 100644 --- a/docs/resources/ssh_key.md +++ b/docs/resources/ssh_key.md @@ -3,12 +3,12 @@ page_title: "xelon_ssh_key Resource - terraform-provider-xelon" subcategory: "" description: |- - Xelon resource to allow you to manage SSH keys + The SSH key resource allows you to manage Xelon SSH keys. --- # xelon_ssh_key (Resource) -Xelon resource to allow you to manage SSH keys +The SSH key resource allows you to manage Xelon SSH keys. ## Example Usage @@ -24,10 +24,9 @@ resource "xelon_ssh_key" "admin" { ### Required -- `name` (String) The name of the SSH key -- `public_key` (String) The text of the public key +- `name` (String) The SSH key name. +- `public_key` (String) The public SSH key material. ### Read-Only -- `fingerprint` (String) The fingerprint of the SSH key -- `id` (String) The ID of this resource. +- `id` (String) The ID of the SSH key. diff --git a/go.mod b/go.mod index 05de3a5..8d385d2 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,19 @@ module github.com/Xelon-AG/terraform-provider-xelon -go 1.22 +go 1.23 -toolchain go1.22.5 +toolchain go1.23.3 require ( - github.com/Xelon-AG/xelon-sdk-go v0.14.1 - github.com/hashicorp/terraform-plugin-framework v1.10.0 - github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 - github.com/hashicorp/terraform-plugin-go v0.23.0 + github.com/Xelon-AG/xelon-sdk-go v0.15.2-0.20241124144649-c71f15f4c7bf + github.com/hashicorp/terraform-plugin-framework v1.13.0 + github.com/hashicorp/terraform-plugin-framework-validators v0.15.0 + github.com/hashicorp/terraform-plugin-go v0.25.0 github.com/hashicorp/terraform-plugin-log v0.9.0 - github.com/hashicorp/terraform-plugin-mux v0.16.0 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 - github.com/hashicorp/terraform-plugin-testing v1.9.0 - github.com/stretchr/testify v1.9.0 + github.com/hashicorp/terraform-plugin-mux v0.17.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 + github.com/hashicorp/terraform-plugin-testing v1.11.0 + github.com/stretchr/testify v1.10.0 ) require ( @@ -32,14 +32,15 @@ require ( github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-plugin v1.6.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/hc-install v0.7.0 // indirect - github.com/hashicorp/hcl/v2 v2.21.0 // indirect + github.com/hashicorp/hc-install v0.9.0 // indirect + github.com/hashicorp/hcl/v2 v2.23.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect - github.com/hashicorp/terraform-json v0.22.1 // indirect + github.com/hashicorp/terraform-json v0.23.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect @@ -55,17 +56,17 @@ require ( github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zclconf/go-cty v1.14.4 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + github.com/zclconf/go-cty v1.15.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.34.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 7bc6782..d8ea765 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= -github.com/Xelon-AG/xelon-sdk-go v0.14.1 h1:aD5Ht8hBYkqccuHG3hhOO/xVpmfNJRXOMp3nMhd0chg= -github.com/Xelon-AG/xelon-sdk-go v0.14.1/go.mod h1:hc1DgVNBbWJPn0GK+HIiNv4npvPsFLY5wMiD//f6/OE= +github.com/Xelon-AG/xelon-sdk-go v0.15.2-0.20241124144649-c71f15f4c7bf h1:zWTVTgeDw07ofB6iwkYEBI1finWDtmuMlfwN7kZnBCQ= +github.com/Xelon-AG/xelon-sdk-go v0.15.2-0.20241124144649-c71f15f4c7bf/go.mod h1:Z8t2YsyXFopxTf6OTUWxIzYrdoPxb8XtzX6Ll50z4Kw= 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/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= @@ -60,37 +60,39 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/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.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= -github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= +github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog= +github.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/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.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= -github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= -github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= -github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= +github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= +github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos= +github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= 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.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= -github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= -github.com/hashicorp/terraform-plugin-framework v1.10.0 h1:xXhICE2Fns1RYZxEQebwkB2+kXouLC932Li9qelozrc= -github.com/hashicorp/terraform-plugin-framework v1.10.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM= -github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 h1:bxZfGo9DIUoLLtHMElsu+zwqI4IsMZQBRRy4iLzZJ8E= -github.com/hashicorp/terraform-plugin-framework-validators v0.13.0/go.mod h1:wGeI02gEhj9nPANU62F2jCaHjXulejm/X+af4PdZaNo= -github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co= -github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ= +github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= +github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= +github.com/hashicorp/terraform-plugin-framework v1.13.0 h1:8OTG4+oZUfKgnfTdPTJwZ532Bh2BobF4H+yBiYJ/scw= +github.com/hashicorp/terraform-plugin-framework v1.13.0/go.mod h1:j64rwMGpgM3NYXTKuxrCnyubQb/4VKldEKlcG8cvmjU= +github.com/hashicorp/terraform-plugin-framework-validators v0.15.0 h1:RXMmu7JgpFjnI1a5QjMCBb11usrW2OtAG+iOTIj5c9Y= +github.com/hashicorp/terraform-plugin-framework-validators v0.15.0/go.mod h1:Bh89/hNmqsEWug4/XWKYBwtnw3tbz5BAy1L1OgvbIaY= +github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks= +github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-mux v0.16.0 h1:RCzXHGDYwUwwqfYYWJKBFaS3fQsWn/ZECEiW7p2023I= -github.com/hashicorp/terraform-plugin-mux v0.16.0/go.mod h1:PF79mAsPc8CpusXPfEVa4X8PtkB+ngWoiUClMrNZlYo= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= -github.com/hashicorp/terraform-plugin-testing v1.9.0 h1:xOsQRqqlHKXpFq6etTxih3ubdK3HVDtfE1IY7Rpd37o= -github.com/hashicorp/terraform-plugin-testing v1.9.0/go.mod h1:fhhVx/8+XNJZTD5o3b4stfZ6+q7z9+lIWigIYdT6/44= +github.com/hashicorp/terraform-plugin-mux v0.17.0 h1:/J3vv3Ps2ISkbLPiZOLspFcIZ0v5ycUXCEQScudGCCw= +github.com/hashicorp/terraform-plugin-mux v0.17.0/go.mod h1:yWuM9U1Jg8DryNfvCp+lH70WcYv6D8aooQxxxIzFDsE= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= +github.com/hashicorp/terraform-plugin-testing v1.11.0 h1:MeDT5W3YHbONJt2aPQyaBsgQeAIckwPX41EUHXEn29A= +github.com/hashicorp/terraform-plugin-testing v1.11.0/go.mod h1:WNAHQ3DcgV/0J+B15WTE6hDvxcUdkPPpnB1FR3M910U= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -139,8 +141,8 @@ github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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= @@ -151,28 +153,28 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= -github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -185,19 +187,19 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= 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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= @@ -208,14 +210,14 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= 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.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 4f27938..4023478 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -17,7 +17,7 @@ import ( ) const ( - defaultBaseURL = "https://hq.xelon.ch/api/service/" + defaultBaseURL = "https://hq.xelon.ch/api/v2/" ) var _ provider.Provider = (*xelonProvider)(nil) @@ -133,7 +133,9 @@ func (p *xelonProvider) DataSources(_ context.Context) []func() datasource.DataS } func (p *xelonProvider) Resources(_ context.Context) []func() resource.Resource { - return []func() resource.Resource{} + return []func() resource.Resource{ + NewSSHKeyResource, + } } func (p *xelonProvider) userAgent() string { diff --git a/internal/provider/resource_xelon_ssh_key.go b/internal/provider/resource_xelon_ssh_key.go new file mode 100644 index 0000000..10857ee --- /dev/null +++ b/internal/provider/resource_xelon_ssh_key.go @@ -0,0 +1,209 @@ +package provider + +import ( + "context" + "net/http" + + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" + + "github.com/Xelon-AG/xelon-sdk-go/xelon" +) + +var ( + _ resource.Resource = (*sshKeyResource)(nil) + _ resource.ResourceWithConfigure = (*sshKeyResource)(nil) + _ resource.ResourceWithImportState = (*sshKeyResource)(nil) +) + +// sshKeyResource is the SSH key resource implementation. +type sshKeyResource struct { + client *xelon.Client +} + +// sshKeyResourceModel maps the tag resource schema data. +type sshKeyResourceModel struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + PublicKey types.String `tfsdk:"public_key"` +} + +func NewSSHKeyResource() resource.Resource { + return &sshKeyResource{} +} + +func (r *sshKeyResource) Metadata(_ context.Context, _ resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = "xelon_ssh_key" +} + +func (r *sshKeyResource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) { + response.Schema = schema.Schema{ + MarkdownDescription: ` +The SSH key resource allows you to manage Xelon SSH keys. +`, + Version: 0, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The ID of the SSH key.", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "The SSH key name.", + Required: true, + }, + "public_key": schema.StringAttribute{ + MarkdownDescription: "The public SSH key material.", + Required: true, + }, + }, + } +} + +func (r *sshKeyResource) Configure(_ context.Context, request resource.ConfigureRequest, response *resource.ConfigureResponse) { + if request.ProviderData == nil { + return + } + + client, ok := request.ProviderData.(*xelon.Client) + if !ok { + response.Diagnostics.AddError( + "Unconfigured Xelon client", + "Please report this issue to the provider developers.", + ) + return + } + + r.client = client +} + +func (r *sshKeyResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var data sshKeyResourceModel + + // read plan data into the model + diags := request.Plan.Get(ctx, &data) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + createRequest := &xelon.SSHKeyCreateRequest{ + SSHKey: xelon.SSHKey{ + Name: data.Name.ValueString(), + PublicKey: data.PublicKey.ValueString(), + }, + } + tflog.Debug(ctx, "Creating SSH key", map[string]any{"payload": createRequest}) + sshKey, _, err := r.client.SSHKeys.Create(ctx, createRequest) + if err != nil { + response.Diagnostics.AddError("Unable to create SSH key", err.Error()) + return + } + tflog.Debug(ctx, "Created SSH key", map[string]any{"data": sshKey}) + + // map response body to attributes + data.ID = types.StringValue(sshKey.ID) + data.Name = types.StringValue(sshKey.Name) + data.PublicKey = types.StringValue(sshKey.PublicKey) + + diags = response.State.Set(ctx, &data) + response.Diagnostics.Append(diags...) +} + +func (r *sshKeyResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + var data sshKeyResourceModel + + // read state data into the model + diags := request.State.Get(ctx, &data) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + sshKeyID := data.ID.ValueString() + tflog.Debug(ctx, "Getting SSH key", map[string]any{"ssh_key_id": sshKeyID}) + sshKey, resp, err := r.client.SSHKeys.Get(ctx, sshKeyID) + if err != nil { + if resp != nil && resp.StatusCode == http.StatusNotFound { + // if the tag is somehow already destroyed, mark as successfully gone + response.State.RemoveResource(ctx) + return + } + response.Diagnostics.AddError("Unable to get SSH key", err.Error()) + return + } + tflog.Debug(ctx, "Got SSH key", map[string]any{"data": sshKey}) + + // map response body to attributes + data.ID = types.StringValue(sshKey.ID) + data.Name = types.StringValue(sshKey.Name) + data.PublicKey = types.StringValue(sshKey.PublicKey) + + diags = response.State.Set(ctx, &data) + response.Diagnostics.Append(diags...) +} + +func (r *sshKeyResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + var data sshKeyResourceModel + + // read plan data into the model + diags := request.Plan.Get(ctx, &data) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + sshKeyID := data.ID.ValueString() + updateRequest := &xelon.SSHKeyUpdateRequest{ + SSHKey: xelon.SSHKey{ + Name: data.Name.ValueString(), + PublicKey: data.PublicKey.ValueString(), + }, + } + tflog.Debug(ctx, "Updating SSH key", map[string]any{"payload": updateRequest, "ssh_key_id": sshKeyID}) + sshKey, _, err := r.client.SSHKeys.Update(ctx, sshKeyID, updateRequest) + if err != nil { + response.Diagnostics.AddError("Unable to update SSH key", err.Error()) + return + } + tflog.Debug(ctx, "Updated SSH key", map[string]any{"data": sshKey}) + + // map response body to attributes + data.ID = types.StringValue(sshKey.ID) + data.Name = types.StringValue(sshKey.Name) + data.PublicKey = types.StringValue(sshKey.PublicKey) + + diags = response.State.Set(ctx, &data) + response.Diagnostics.Append(diags...) +} + +func (r *sshKeyResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + var data sshKeyResourceModel + + // read state data into the model + diags := request.State.Get(ctx, &data) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + sshKeyID := data.ID.ValueString() + tflog.Debug(ctx, "Deleting SSH key", map[string]any{"ssh_key_id": sshKeyID}) + _, err := r.client.SSHKeys.Delete(ctx, sshKeyID) + if err != nil { + response.Diagnostics.AddError("Unable to delete SSH key", err.Error()) + return + } + tflog.Debug(ctx, "Deleted SSH key", map[string]any{"ssh_key_id": sshKeyID}) +} + +func (r *sshKeyResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), request, response) +} diff --git a/internal/xelon/provider.go b/internal/xelon/provider.go index dd23262..ecc1922 100644 --- a/internal/xelon/provider.go +++ b/internal/xelon/provider.go @@ -14,8 +14,8 @@ func New(version string) func() *schema.Provider { "base_url": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("XELON_BASE_URL", "https://hq.xelon.ch/api/service/"), - Description: "The base URL endpoint for Xelon HQ. Default is `https://hq.xelon.ch/api/service/`. " + + DefaultFunc: schema.EnvDefaultFunc("XELON_BASE_URL", "https://hq.xelon.ch/api/v2/"), + Description: "The base URL endpoint for Xelon HQ. Default is `https://hq.xelon.ch/api/v2/`. " + "Alternatively, can be configured using the `XELON_BASE_URL` environment variable.", }, "client_id": { @@ -43,7 +43,7 @@ func New(version string) func() *schema.Provider { "xelon_device": resourceXelonDevice(), "xelon_network": resourceXelonNetwork(), "xelon_persistent_storage": resourceXelonPersistentStorage(), - "xelon_ssh_key": resourceXelonSSHKey(), + // "xelon_ssh_key": resourceXelonSSHKey(), }, } diff --git a/internal/xelon/resource_xelon_ssh_key.go b/internal/xelon/resource_xelon_ssh_key.go index e41fe29..61c0b0c 100644 --- a/internal/xelon/resource_xelon_ssh_key.go +++ b/internal/xelon/resource_xelon_ssh_key.go @@ -1,137 +1,137 @@ package xelon - -import ( - "context" - "fmt" - "strconv" - "strings" - - "github.com/hashicorp/terraform-plugin-log/tflog" - "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" - - "github.com/Xelon-AG/xelon-sdk-go/xelon" -) - -func resourceXelonSSHKey() *schema.Resource { - return &schema.Resource{ - Description: "Xelon resource to allow you to manage SSH keys", - - CreateContext: resourceXelonSSHKeyCreate, - ReadContext: resourceXelonSSHKeyRead, - UpdateContext: resourceXelonSSHKeyUpdate, - DeleteContext: resourceXelonSSHKeyDelete, - - SchemaVersion: 0, - - Schema: map[string]*schema.Schema{ - "fingerprint": { - Type: schema.TypeString, - Computed: true, - Description: "The fingerprint of the SSH key", - }, - - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the SSH key", - ValidateFunc: validation.NoZeroValues, - }, - - "public_key": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The text of the public key", - DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool { - return strings.TrimSpace(oldValue) == strings.TrimSpace(newValue) - }, - ValidateFunc: validation.NoZeroValues, - }, - }, - } -} - -func resourceXelonSSHKeyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client := meta.(*xelon.Client) - - createRequest := &xelon.SSHKeyCreateRequest{ - SSHKey: &xelon.SSHKey{ - Name: d.Get("name").(string), - PublicKey: d.Get("public_key").(string), - }, - } - - tflog.Debug(ctx, "Creating Xelon SSH Key", map[string]interface{}{ - "configuration": createRequest, - }) - - key, _, err := client.SSHKeys.Create(ctx, createRequest) - if err != nil { - return diag.FromErr(fmt.Errorf("creating Xelon SSH Key: %w", err)) - } - - d.SetId(strconv.Itoa(key.ID)) - - tflog.Info(ctx, "Created Xelon SSH Key", map[string]interface{}{ - "id": key.ID, - "fingerprint": key.Fingerprint, - }) - - return resourceXelonSSHKeyRead(ctx, d, meta) -} - -func resourceXelonSSHKeyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client := meta.(*xelon.Client) - - id, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.FromErr(fmt.Errorf("invalid Xelon SSH Key ID: %w", err)) - } - - keys, _, err := client.SSHKeys.List(ctx) - if err != nil { - return diag.FromErr(fmt.Errorf("retrieving Xelon SSH Keys: %w", err)) - } - for _, key := range keys { - // will be refactored later when get method for single key is available - if key.ID == id { - _ = d.Set("fingerprint", key.Fingerprint) - _ = d.Set("name", key.Name) - return nil - } - } - - return nil -} - -func resourceXelonSSHKeyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - // workaround because of missing update method for single key - resourceXelonSSHKeyDelete(ctx, d, meta) - resourceXelonSSHKeyCreate(ctx, d, meta) - - return nil -} - -func resourceXelonSSHKeyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client := meta.(*xelon.Client) - - id, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.FromErr(fmt.Errorf("invalid Xelon SSH Key ID: %w", err)) - } - - tflog.Debug(ctx, "Deleting Xelon SSH Key", map[string]interface{}{ - "id": id, - }) - - _, err = client.SSHKeys.Delete(ctx, id) - if err != nil { - return diag.FromErr(fmt.Errorf("deleting Xelon SSH Key: %w", err)) - } - - d.SetId("") - - return nil -} +// +// import ( +// "context" +// "fmt" +// "strconv" +// "strings" +// +// "github.com/hashicorp/terraform-plugin-log/tflog" +// "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" +// +// "github.com/Xelon-AG/xelon-sdk-go/xelon" +// ) +// +// func resourceXelonSSHKey() *schema.Resource { +// return &schema.Resource{ +// Description: "Xelon resource to allow you to manage SSH keys", +// +// CreateContext: resourceXelonSSHKeyCreate, +// ReadContext: resourceXelonSSHKeyRead, +// UpdateContext: resourceXelonSSHKeyUpdate, +// DeleteContext: resourceXelonSSHKeyDelete, +// +// SchemaVersion: 0, +// +// Schema: map[string]*schema.Schema{ +// "fingerprint": { +// Type: schema.TypeString, +// Computed: true, +// Description: "The fingerprint of the SSH key", +// }, +// +// "name": { +// Type: schema.TypeString, +// Required: true, +// Description: "The name of the SSH key", +// ValidateFunc: validation.NoZeroValues, +// }, +// +// "public_key": { +// Type: schema.TypeString, +// Required: true, +// ForceNew: true, +// Description: "The text of the public key", +// DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool { +// return strings.TrimSpace(oldValue) == strings.TrimSpace(newValue) +// }, +// ValidateFunc: validation.NoZeroValues, +// }, +// }, +// } +// } +// +// func resourceXelonSSHKeyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +// client := meta.(*xelon.Client) +// +// createRequest := &xelon.SSHKeyCreateRequest{ +// SSHKey: &xelon.SSHKey{ +// Name: d.Get("name").(string), +// PublicKey: d.Get("public_key").(string), +// }, +// } +// +// tflog.Debug(ctx, "Creating Xelon SSH Key", map[string]interface{}{ +// "configuration": createRequest, +// }) +// +// key, _, err := client.SSHKeys.Create(ctx, createRequest) +// if err != nil { +// return diag.FromErr(fmt.Errorf("creating Xelon SSH Key: %w", err)) +// } +// +// d.SetId(strconv.Itoa(key.ID)) +// +// tflog.Info(ctx, "Created Xelon SSH Key", map[string]interface{}{ +// "id": key.ID, +// "fingerprint": key.Fingerprint, +// }) +// +// return resourceXelonSSHKeyRead(ctx, d, meta) +// } +// +// func resourceXelonSSHKeyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +// client := meta.(*xelon.Client) +// +// id, err := strconv.Atoi(d.Id()) +// if err != nil { +// return diag.FromErr(fmt.Errorf("invalid Xelon SSH Key ID: %w", err)) +// } +// +// keys, _, err := client.SSHKeys.List(ctx) +// if err != nil { +// return diag.FromErr(fmt.Errorf("retrieving Xelon SSH Keys: %w", err)) +// } +// for _, key := range keys { +// // will be refactored later when get method for single key is available +// if key.ID == id { +// _ = d.Set("fingerprint", key.Fingerprint) +// _ = d.Set("name", key.Name) +// return nil +// } +// } +// +// return nil +// } +// +// func resourceXelonSSHKeyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +// // workaround because of missing update method for single key +// resourceXelonSSHKeyDelete(ctx, d, meta) +// resourceXelonSSHKeyCreate(ctx, d, meta) +// +// return nil +// } +// +// func resourceXelonSSHKeyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +// client := meta.(*xelon.Client) +// +// id, err := strconv.Atoi(d.Id()) +// if err != nil { +// return diag.FromErr(fmt.Errorf("invalid Xelon SSH Key ID: %w", err)) +// } +// +// tflog.Debug(ctx, "Deleting Xelon SSH Key", map[string]interface{}{ +// "id": id, +// }) +// +// _, err = client.SSHKeys.Delete(ctx, id) +// if err != nil { +// return diag.FromErr(fmt.Errorf("deleting Xelon SSH Key: %w", err)) +// } +// +// d.SetId("") +// +// return nil +// } diff --git a/internal/xelon/resource_xelon_ssh_key_test.go b/internal/xelon/resource_xelon_ssh_key_test.go index dca3a8e..747f966 100644 --- a/internal/xelon/resource_xelon_ssh_key_test.go +++ b/internal/xelon/resource_xelon_ssh_key_test.go @@ -1,138 +1,138 @@ package xelon - -import ( - "context" - "fmt" - "log" - "strconv" - "strings" - "testing" - - "github.com/hashicorp/terraform-plugin-testing/helper/acctest" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-plugin-testing/terraform" - - "github.com/Xelon-AG/xelon-sdk-go/xelon" -) - -func init() { - resource.AddTestSweepers("xelon_ssh_key", &resource.Sweeper{ - Name: "xelon_ssh_key", - F: testSweepSSHKeys, - }) -} - -func testSweepSSHKeys(region string) error { - ctx := context.Background() - client, err := sharedClient(region) - if err != nil { - return err - } - - sshKeys, _, err := client.SSHKeys.List(ctx) - if err != nil { - return fmt.Errorf("getting ssh keys list: %s", err) - } - - for _, sshKey := range sshKeys { - if strings.HasPrefix(sshKey.Name, accTestPrefix) { - log.Printf("[DEBUG] Deleting xelon_ssh_key: %s (%d)", sshKey.Name, sshKey.ID) - _, err := client.SSHKeys.Delete(ctx, sshKey.ID) - if err != nil { - log.Printf("Error destroying %s during sweep: %s", sshKey.Name, err) - } - } - } - - return nil -} - -func TestAccResourceXelonSSHKey_basic(t *testing.T) { - var sshKey xelon.SSHKey - sshKeyName := fmt.Sprintf("%s-%s", accTestPrefix, acctest.RandString(10)) - sshKeyPublic, _, err := acctest.RandSSHKeyPair("xelon@ssh-acceptance-test") - if err != nil { - t.Fatalf("could not generate test SSH key: %s", err) - } - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviderFactories, - CheckDestroy: testAccCheckSSHKeyDestroy, - - Steps: []resource.TestStep{ - { - Config: testAccResourceXelonSSHKeyConfig(sshKeyName, sshKeyPublic), - Check: resource.ComposeTestCheckFunc( - testAccCheckSSHKeyExists("xelon_ssh_key.test", &sshKey), - resource.TestCheckResourceAttrSet("xelon_ssh_key.test", "id"), - resource.TestCheckResourceAttrSet("xelon_ssh_key.test", "fingerprint"), - resource.TestCheckResourceAttr("xelon_ssh_key.test", "name", sshKeyName), - resource.TestCheckResourceAttr("xelon_ssh_key.test", "public_key", sshKeyPublic), - ), - }, - }, - }) -} - -func testAccCheckSSHKeyExists(n string, sshKey *xelon.SSHKey) 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 SSH Key ID is set") - } - - client := testAccProvider.Meta().(*xelon.Client) - retrievedSSHKeys, _, err := client.SSHKeys.List(context.Background()) - if err != nil { - return err - } - - for _, retrievedSSHKey := range retrievedSSHKeys { - sshKeyID := strconv.Itoa(retrievedSSHKey.ID) - if sshKeyID == rs.Primary.ID { - sshKey = &retrievedSSHKey - return nil - } - } - - return fmt.Errorf("SSH Key not found") - } -} - -func testAccCheckSSHKeyDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*xelon.Client) - - for _, rs := range s.RootModule().Resources { - if rs.Type != "xelon_ssh_key" { - continue - } - - sshKeys, _, err := client.SSHKeys.List(context.Background()) - if err != nil { - return err - } - - for _, sshKey := range sshKeys { - sshKeyID := strconv.Itoa(sshKey.ID) - if sshKeyID == rs.Primary.ID { - return fmt.Errorf("SSH Key (%s) still exists", rs.Primary.ID) - } - } - } - - return nil -} - -func testAccResourceXelonSSHKeyConfig(name, publicKey string) string { - return fmt.Sprintf(` -resource "xelon_ssh_key" "test" { - name = "%s" - public_key = "%s" -} -`, name, publicKey) -} +// +// import ( +// "context" +// "fmt" +// "log" +// "strconv" +// "strings" +// "testing" +// +// "github.com/hashicorp/terraform-plugin-testing/helper/acctest" +// "github.com/hashicorp/terraform-plugin-testing/helper/resource" +// "github.com/hashicorp/terraform-plugin-testing/terraform" +// +// "github.com/Xelon-AG/xelon-sdk-go/xelon" +// ) +// +// func init() { +// resource.AddTestSweepers("xelon_ssh_key", &resource.Sweeper{ +// Name: "xelon_ssh_key", +// F: testSweepSSHKeys, +// }) +// } +// +// func testSweepSSHKeys(region string) error { +// ctx := context.Background() +// client, err := sharedClient(region) +// if err != nil { +// return err +// } +// +// sshKeys, _, err := client.SSHKeys.List(ctx) +// if err != nil { +// return fmt.Errorf("getting ssh keys list: %s", err) +// } +// +// for _, sshKey := range sshKeys { +// if strings.HasPrefix(sshKey.Name, accTestPrefix) { +// log.Printf("[DEBUG] Deleting xelon_ssh_key: %s (%d)", sshKey.Name, sshKey.ID) +// _, err := client.SSHKeys.Delete(ctx, sshKey.ID) +// if err != nil { +// log.Printf("Error destroying %s during sweep: %s", sshKey.Name, err) +// } +// } +// } +// +// return nil +// } +// +// func TestAccResourceXelonSSHKey_basic(t *testing.T) { +// var sshKey xelon.SSHKey +// sshKeyName := fmt.Sprintf("%s-%s", accTestPrefix, acctest.RandString(10)) +// sshKeyPublic, _, err := acctest.RandSSHKeyPair("xelon@ssh-acceptance-test") +// if err != nil { +// t.Fatalf("could not generate test SSH key: %s", err) +// } +// +// resource.ParallelTest(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// ProviderFactories: testAccProviderFactories, +// CheckDestroy: testAccCheckSSHKeyDestroy, +// +// Steps: []resource.TestStep{ +// { +// Config: testAccResourceXelonSSHKeyConfig(sshKeyName, sshKeyPublic), +// Check: resource.ComposeTestCheckFunc( +// testAccCheckSSHKeyExists("xelon_ssh_key.test", &sshKey), +// resource.TestCheckResourceAttrSet("xelon_ssh_key.test", "id"), +// resource.TestCheckResourceAttrSet("xelon_ssh_key.test", "fingerprint"), +// resource.TestCheckResourceAttr("xelon_ssh_key.test", "name", sshKeyName), +// resource.TestCheckResourceAttr("xelon_ssh_key.test", "public_key", sshKeyPublic), +// ), +// }, +// }, +// }) +// } +// +// func testAccCheckSSHKeyExists(n string, sshKey *xelon.SSHKey) 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 SSH Key ID is set") +// } +// +// client := testAccProvider.Meta().(*xelon.Client) +// retrievedSSHKeys, _, err := client.SSHKeys.List(context.Background()) +// if err != nil { +// return err +// } +// +// for _, retrievedSSHKey := range retrievedSSHKeys { +// sshKeyID := strconv.Itoa(retrievedSSHKey.ID) +// if sshKeyID == rs.Primary.ID { +// sshKey = &retrievedSSHKey +// return nil +// } +// } +// +// return fmt.Errorf("SSH Key not found") +// } +// } +// +// func testAccCheckSSHKeyDestroy(s *terraform.State) error { +// client := testAccProvider.Meta().(*xelon.Client) +// +// for _, rs := range s.RootModule().Resources { +// if rs.Type != "xelon_ssh_key" { +// continue +// } +// +// sshKeys, _, err := client.SSHKeys.List(context.Background()) +// if err != nil { +// return err +// } +// +// for _, sshKey := range sshKeys { +// sshKeyID := strconv.Itoa(sshKey.ID) +// if sshKeyID == rs.Primary.ID { +// return fmt.Errorf("SSH Key (%s) still exists", rs.Primary.ID) +// } +// } +// } +// +// return nil +// } +// +// func testAccResourceXelonSSHKeyConfig(name, publicKey string) string { +// return fmt.Sprintf(` +// resource "xelon_ssh_key" "test" { +// name = "%s" +// public_key = "%s" +// } +// `, name, publicKey) +// }