diff --git a/.github/workflows/scoreboard.yaml b/.github/workflows/scoreboard.yaml index 973b598..5041581 100644 --- a/.github/workflows/scoreboard.yaml +++ b/.github/workflows/scoreboard.yaml @@ -2,7 +2,7 @@ name: Scorecard supply-chain security on: branch_protection_rule: schedule: - - cron: '30 0 * * 6' + - cron: '30 6 * * 6' push: branches: [ "main" ] diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 516c72d..7d59bf3 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -lucastesson@protonmail.com. +ctfer-io@protonmail.com. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/LICENSE b/LICENSE index c342233..743bd88 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,201 @@ -MIT License - -Copyright (c) 2023 Lucas TESSON - PandatiX - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 CTFer.io + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index c07598a..37b0788 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,29 @@
-

Terraform Provider for CTFd

+

OpenTofu Provider for CTFd

Time for CTF(d) as Code

- reference - go report - Coverage Status + reference + go report + Coverage Status
- License - CI - CodeQL + License + CI + CodeQL
- OpenSSF Scoreboard + OpenSSF Scoreboard

## Why creating this ? -Terraform is used to manage resources that have lifecycles, to sum it up. +OpenTofu is used to manage resources that have lifecycles, configurations, to sum it up. -Well, that is the case of CTFd : it handles challenges that could be created, modified and deleted. -With some work to leverage the unsteady CTFd's API, Terraform is now able to manage them as cloud resources bringing you to opportunity of **CTF as Code**. +That is the case of CTFd: it handles challenges that could be created, modified and deleted. +With some work to leverage the unsteady CTFd's API, OpenTofu is now able to manage them as cloud resources bringing you to opportunity of **CTF as Code**. It avoids shitty scripts, `ctfcli` and other tools that does not solve the problem of reproductibility, ease of deployment and resiliency. ## How to use it ? -With the **Terraform Provider for CTFd**, you could setup your CTFd challenge using the following configuration. +With the **OpenTofu Provider for CTFd**, you could setup your CTFd challenge using the following configuration. ```hcl resource "ctfd_challenge" "my_challenge" { name = "My Challenge" diff --git a/SECURITY.md b/SECURITY.md index f79fe32..71229dc 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,13 +1,13 @@ # Reporting Security Issues -Please report any security issues you discovered in the API to lucastesson@protonmail.com. +Please report any security issues you discovered in the API to ctfer-io@protonmail.com. We will assess the risk, plus make a fix available before we create a GitHub issue. -In case the vulnerability is into a dependency or Terraform itself, do not report this to us but refer to their policies. +In case the vulnerability is into a dependency or OpenTofu itself, please refer to their security policy directly. Thank you for your contribution. ## Refering to this repository -To refer to this repository using a CPE v2.3, please use `cpe:2.3:a:pandatix:terraform-provider-ctfd:*:*:*:*:*:terraform:*:*` with the `version` set to the tag you are using. +To refer to this repository using a CPE v2.3, please use `cpe:2.3:a:ctfer-io:tofu-provider-ctfd:*:*:*:*:*:*:*:*` with the `version` set to the tag you are using. diff --git a/examples/provider-install-verification/main.tf b/examples/provider-install-verification/main.tf index b04d156..b48b696 100644 --- a/examples/provider-install-verification/main.tf +++ b/examples/provider-install-verification/main.tf @@ -1,7 +1,7 @@ terraform { required_providers { ctfd = { - source = "registry.terraform.io/pandatix/ctfd" + source = "registry.terraform.io/ctfer-io/ctfd" } } } diff --git a/go.mod b/go.mod index 6e4cf61..a965ef3 100644 --- a/go.mod +++ b/go.mod @@ -1,34 +1,62 @@ -module github.com/pandatix/terraform-provider-ctfd +module github.com/ctfer-io/tofu-provider-ctfd go 1.21 require ( - github.com/hashicorp/terraform-plugin-framework v1.3.5 - github.com/hashicorp/terraform-plugin-log v0.9.0 - github.com/pandatix/go-ctfd v0.1.9 + github.com/opentofu/terraform-plugin-framework v1.3.4 + github.com/opentofu/terraform-plugin-go v0.18.0 + github.com/opentofu/terraform-plugin-log v0.9.0 + github.com/opentofu/terraform-plugin-testing v1.5.1 + github.com/ctfer-io/go-ctfd v0.1.9 ) require ( + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect + github.com/agext/levenshtein v1.2.2 // indirect + github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/cloudflare/circl v1.3.3 // indirect github.com/fatih/color v1.13.0 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/gorilla/schema v1.2.0 // indirect + github.com/hashicorp/errwrap v1.0.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.5.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.4.10 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/terraform-plugin-go v0.18.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/hc-install v0.5.2 // indirect + github.com/hashicorp/hcl/v2 v2.17.0 // indirect + github.com/hashicorp/logutils v1.0.0 // indirect + github.com/hashicorp/terraform-exec v0.18.1 // indirect + github.com/hashicorp/terraform-json v0.17.1 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.28.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.1 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect - github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect + github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // 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/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/zclconf/go-cty v1.13.3 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 // indirect + golang.org/x/mod v0.11.0 // indirect golang.org/x/net v0.11.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.56.1 // indirect google.golang.org/protobuf v1.31.0 // indirect diff --git a/go.sum b/go.sum index 616303e..2c9ad19 100644 --- a/go.sum +++ b/go.sum @@ -1,72 +1,186 @@ +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= +github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= +github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= +github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC2MDs4ee8= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= +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/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= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= +github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/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.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk= github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= +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/terraform-plugin-framework v1.3.5 h1:FJ6s3CVWVAxlhiF/jhy6hzs4AnPHiflsp9KgzTGl1wo= -github.com/hashicorp/terraform-plugin-framework v1.3.5/go.mod h1:2gGDpWiTI0irr9NSTLFAKlTi6KwGti3AoU19rFqU30o= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.5.2 h1:SfwMFnEXVVirpwkDuSF5kymUOhrUxrTq3udEseZdOD0= +github.com/hashicorp/hc-install v0.5.2/go.mod h1:9QISwe6newMWIfEiXpzuu1k9HAGtQYgnSH8H9T8wmoI= +github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= +github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= +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.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4= +github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980= +github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= +github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= +github.com/hashicorp/terraform-plugin-framework v1.3.4 h1:dOTLsALgmQu+PawAvhfGQ04H0MeIz3EZmBw7OFvj7qs= +github.com/hashicorp/terraform-plugin-framework v1.3.4/go.mod h1:2gGDpWiTI0irr9NSTLFAKlTi6KwGti3AoU19rFqU30o= github.com/hashicorp/terraform-plugin-go v0.18.0 h1:IwTkOS9cOW1ehLd/rG0y+u/TGLK9y6fGoBjXVUquzpE= github.com/hashicorp/terraform-plugin-go v0.18.0/go.mod h1:l7VK+2u5Kf2y+A+742GX0ouLut3gttudmvMgN0PA74Y= 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-sdk/v2 v2.28.0 h1:gY4SG34ANc6ZSeWEKC9hDTChY0ZiN+Myon17fSA0Xgc= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.28.0/go.mod h1:deXEw/iJXtJxNV9d1c/OVJrvL7Zh0a++v7rzokW6wVY= +github.com/hashicorp/terraform-plugin-testing v1.5.1 h1:T4aQh9JAhmWo4+t1A7x+rnxAJHCDIYW9kXyo4sVO92c= +github.com/hashicorp/terraform-plugin-testing v1.5.1/go.mod h1:dg8clO6K59rZ8w9EshBmDp1CxTIPu3yA4iaDpX1h5u0= github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM= github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= -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/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= 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.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-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/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= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pandatix/go-ctfd v0.1.9 h1:4ZiydbZgV2kXNTRnqyJfChFuxUt7W8RRsfw9T0LicmI= github.com/pandatix/go-ctfd v0.1.9/go.mod h1:RzuIfvJGweW7/a8uo+STh9e6m2Hbi8o1DskmeHljiK4= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= +github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.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= github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +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/zclconf/go-cty v1.13.3 h1:m+b9q3YDbg6Bec5rr+KGy1MzEVzY/jC2X+YX4yqKtHI= +github.com/zclconf/go-cty v1.13.3/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +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.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U= +golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +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.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +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-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= @@ -76,6 +190,10 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/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= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.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= diff --git a/internal/provider/challenge/file_subdata_source.go b/internal/provider/challenge/file_subdata_source.go index 100fbb5..a70a85d 100644 --- a/internal/provider/challenge/file_subdata_source.go +++ b/internal/provider/challenge/file_subdata_source.go @@ -1,8 +1,8 @@ package challenge -import "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +import "github.com/opentofu/terraform-plugin-framework/datasource/schema" -func fileSubdatasourceAttributes() map[string]schema.Attribute { +func FileSubdatasourceAttributes() map[string]schema.Attribute { return map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, diff --git a/internal/provider/challenge/file_subresource.go b/internal/provider/challenge/file_subresource.go index 07c213b..55a1c1f 100644 --- a/internal/provider/challenge/file_subresource.go +++ b/internal/provider/challenge/file_subresource.go @@ -6,16 +6,16 @@ import ( "fmt" "strconv" - "github.com/hashicorp/terraform-plugin-framework/diag" - "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/pandatix/go-ctfd/api" + "github.com/ctfer-io/go-ctfd/api" + "github.com/opentofu/terraform-plugin-framework/diag" + "github.com/opentofu/terraform-plugin-framework/resource/schema" + "github.com/opentofu/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/opentofu/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/opentofu/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-log/tflog" ) -type fileSubresourceModel struct { +type FileSubresourceModel struct { ID types.String `tfsdk:"id"` Name types.String `tfsdk:"name"` Location types.String `tfsdk:"location"` @@ -24,7 +24,7 @@ type fileSubresourceModel struct { ContentB64 types.String `tfsdk:"contentb64"` } -func fileSubresourceAttributes() map[string]schema.Attribute { +func FileSubresourceAttributes() map[string]schema.Attribute { return map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, @@ -61,7 +61,7 @@ func fileSubresourceAttributes() map[string]schema.Attribute { } // Read fetches all the file's information, only requiring the ID to be set. -func (file *fileSubresourceModel) Read(ctx context.Context, diags diag.Diagnostics, client *api.Client) { +func (file *FileSubresourceModel) Read(ctx context.Context, diags diag.Diagnostics, client *api.Client) { content, err := client.GetFileContent(&api.File{ Location: file.Location.ValueString(), }, api.WithContext(ctx)) @@ -76,7 +76,7 @@ func (file *fileSubresourceModel) Read(ctx context.Context, diags diag.Diagnosti file.PropagateContent(ctx, diags) } -func (data *fileSubresourceModel) Create(ctx context.Context, diags diag.Diagnostics, client *api.Client, challengeID string) { +func (data *FileSubresourceModel) Create(ctx context.Context, diags diag.Diagnostics, client *api.Client, challengeID string) { // Fetch raw or base64 content prior to creating it with raw data.PropagateContent(ctx, diags) if diags.HasError() { @@ -104,7 +104,7 @@ func (data *fileSubresourceModel) Create(ctx context.Context, diags diag.Diagnos data.Location = types.StringValue(res[0].Location) } -func (data *fileSubresourceModel) Delete(ctx context.Context, diags diag.Diagnostics, client *api.Client) { +func (data *FileSubresourceModel) Delete(ctx context.Context, diags diag.Diagnostics, client *api.Client) { if err := client.DeleteFile(data.ID.ValueString(), api.WithContext(ctx)); err != nil { diags.AddError( "Client Error", @@ -116,7 +116,7 @@ func (data *fileSubresourceModel) Delete(ctx context.Context, diags diag.Diagnos tflog.Trace(ctx, "deleted a file") } -func (data *fileSubresourceModel) PropagateContent(ctx context.Context, diags diag.Diagnostics) { +func (data *FileSubresourceModel) PropagateContent(ctx context.Context, diags diag.Diagnostics) { // If the other content source is set, get the other from it if len(data.Content.ValueString()) != 0 { cb64 := base64.StdEncoding.EncodeToString([]byte(data.Content.ValueString())) diff --git a/internal/provider/challenge/flag_subdata_source.go b/internal/provider/challenge/flag_subdata_source.go index 853ee29..9af71a7 100644 --- a/internal/provider/challenge/flag_subdata_source.go +++ b/internal/provider/challenge/flag_subdata_source.go @@ -1,10 +1,10 @@ package challenge import ( - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/opentofu/terraform-plugin-framework/datasource/schema" ) -func flagSubdatasourceAttributes() map[string]schema.Attribute { +func FlagSubdatasourceAttributes() map[string]schema.Attribute { return map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, diff --git a/internal/provider/challenge/flag_subresource.go b/internal/provider/challenge/flag_subresource.go index 11411a8..580d0e7 100644 --- a/internal/provider/challenge/flag_subresource.go +++ b/internal/provider/challenge/flag_subresource.go @@ -5,24 +5,24 @@ import ( "fmt" "strconv" - "github.com/hashicorp/terraform-plugin-framework/diag" - "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/stringdefault" - "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/pandatix/go-ctfd/api" + "github.com/ctfer-io/go-ctfd/api" + "github.com/opentofu/terraform-plugin-framework/diag" + "github.com/opentofu/terraform-plugin-framework/resource/schema" + "github.com/opentofu/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/opentofu/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/opentofu/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/opentofu/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-log/tflog" ) -type flagSubresourceModel struct { +type FlagSubresourceModel struct { ID types.String `tfsdk:"id"` Content types.String `tfsdk:"content"` Data types.String `tfsdk:"data"` Type types.String `tfsdk:"type"` } -func flagSubresourceAttributes() map[string]schema.Attribute { +func FlagSubresourceAttributes() map[string]schema.Attribute { return map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, @@ -50,7 +50,7 @@ func flagSubresourceAttributes() map[string]schema.Attribute { } } -func (data *flagSubresourceModel) Create(ctx context.Context, diags diag.Diagnostics, client *api.Client, challengeID string) { +func (data *FlagSubresourceModel) Create(ctx context.Context, diags diag.Diagnostics, client *api.Client, challengeID string) { res, err := client.PostFlags(&api.PostFlagsParams{ Challenge: challengeID, Content: data.Content.ValueString(), @@ -70,7 +70,7 @@ func (data *flagSubresourceModel) Create(ctx context.Context, diags diag.Diagnos data.ID = types.StringValue(strconv.Itoa(res.ID)) } -func (data *flagSubresourceModel) Update(ctx context.Context, diags diag.Diagnostics, client *api.Client) { +func (data *FlagSubresourceModel) Update(ctx context.Context, diags diag.Diagnostics, client *api.Client) { res, err := client.PatchFlag(data.ID.ValueString(), &api.PatchFlagParams{ Content: data.Content.ValueString(), Data: data.Data.ValueString(), @@ -92,7 +92,7 @@ func (data *flagSubresourceModel) Update(ctx context.Context, diags diag.Diagnos data.Type = types.StringValue(res.Type) } -func (data *flagSubresourceModel) Delete(ctx context.Context, diags diag.Diagnostics, client *api.Client) { +func (data *FlagSubresourceModel) Delete(ctx context.Context, diags diag.Diagnostics, client *api.Client) { if err := client.DeleteFlag(data.ID.ValueString(), api.WithContext(ctx)); err != nil { diags.AddError( "Client Error", diff --git a/internal/provider/challenge/hint_subdata_source.go b/internal/provider/challenge/hint_subdata_source.go index 1d2207e..7b0bdfe 100644 --- a/internal/provider/challenge/hint_subdata_source.go +++ b/internal/provider/challenge/hint_subdata_source.go @@ -1,11 +1,11 @@ package challenge import ( - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-framework/datasource/schema" + "github.com/opentofu/terraform-plugin-framework/types" ) -func hintSubdatasourceAttributes() map[string]schema.Attribute { +func HintSubdatasourceAttributes() map[string]schema.Attribute { return map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, diff --git a/internal/provider/challenge/hint_subresource.go b/internal/provider/challenge/hint_subresource.go index feb653f..f453768 100644 --- a/internal/provider/challenge/hint_subresource.go +++ b/internal/provider/challenge/hint_subresource.go @@ -5,26 +5,26 @@ import ( "fmt" "strconv" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "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/pandatix/go-ctfd/api" + "github.com/ctfer-io/go-ctfd/api" + "github.com/opentofu/terraform-plugin-framework/diag" + "github.com/opentofu/terraform-plugin-framework/resource/schema" + "github.com/opentofu/terraform-plugin-framework/resource/schema/int64default" + "github.com/opentofu/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/opentofu/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/opentofu/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-log/tflog" ) // TODO requirements can be set manually, but can't be automatised. Hint may be a complete resource -type hintSubresourceModel struct { +type HintSubresourceModel struct { ID types.String `tfsdk:"id"` Content types.String `tfsdk:"content"` Cost types.Int64 `tfsdk:"cost"` Requirements []types.String `tfsdk:"requirements"` } -func hintSubresourceAttributes() map[string]schema.Attribute { +func HintSubresourceAttributes() map[string]schema.Attribute { return map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, @@ -48,7 +48,7 @@ func hintSubresourceAttributes() map[string]schema.Attribute { } } -func (data *hintSubresourceModel) Create(ctx context.Context, diags diag.Diagnostics, client *api.Client, challengeID string) { +func (data *HintSubresourceModel) Create(ctx context.Context, diags diag.Diagnostics, client *api.Client, challengeID string) { preq := make([]int, 0, len(data.Requirements)) for _, req := range data.Requirements { hintID, _ := strconv.Atoi(req.ValueString()) @@ -76,7 +76,7 @@ func (data *hintSubresourceModel) Create(ctx context.Context, diags diag.Diagnos data.ID = types.StringValue(strconv.Itoa(res.ID)) } -func (data *hintSubresourceModel) Update(ctx context.Context, diags diag.Diagnostics, client *api.Client) { +func (data *HintSubresourceModel) Update(ctx context.Context, diags diag.Diagnostics, client *api.Client) { preq := make([]int, 0, len(data.Requirements)) for _, req := range data.Requirements { hintID, _ := strconv.Atoi(req.ValueString()) @@ -109,7 +109,7 @@ func (data *hintSubresourceModel) Update(ctx context.Context, diags diag.Diagnos data.Requirements = dPreq } -func (data *hintSubresourceModel) Delete(ctx context.Context, diags diag.Diagnostics, client *api.Client) { +func (data *HintSubresourceModel) Delete(ctx context.Context, diags diag.Diagnostics, client *api.Client) { if err := client.DeleteHint(data.ID.ValueString(), api.WithContext(ctx)); err != nil { diags.AddError( "Client Error", diff --git a/internal/provider/challenge/requirements_subresource.go b/internal/provider/challenge/requirements_subresource.go index 7bd10fa..da514ba 100644 --- a/internal/provider/challenge/requirements_subresource.go +++ b/internal/provider/challenge/requirements_subresource.go @@ -1,33 +1,36 @@ package challenge -import "github.com/hashicorp/terraform-plugin-framework/types" +import ( + "github.com/ctfer-io/terraform-provider-ctfd/internal/provider/utils" + "github.com/opentofu/terraform-plugin-framework/types" +) var ( - behaviorHidden = types.StringValue("hidden") - behaviorAnonymized = types.StringValue("anonymized") + BehaviorHidden = types.StringValue("hidden") + BehaviorAnonymized = types.StringValue("anonymized") ) -type requirementsSubresourceModel struct { +type RequirementsSubresourceModel struct { Behavior types.String `tfsdk:"behavior"` Prerequisites []types.String `tfsdk:"prerequisites"` } -func getAnon(str types.String) *bool { +func GetAnon(str types.String) *bool { switch { - case str.Equal(behaviorHidden): + case str.Equal(BehaviorHidden): return nil - case str.Equal(behaviorAnonymized): - return ptr(true) + case str.Equal(BehaviorAnonymized): + return utils.Ptr(true) } panic("invalid anonymization value: " + str.ValueString()) } -func fromAnon(b *bool) types.String { +func FromAnon(b *bool) types.String { if b == nil { - return behaviorHidden + return BehaviorHidden } if *b { - return behaviorAnonymized + return BehaviorAnonymized } panic("invalid anonymization value, got boolean false") } diff --git a/internal/provider/challenge/challenge_data_source.go b/internal/provider/challenge_data_source.go similarity index 82% rename from internal/provider/challenge/challenge_data_source.go rename to internal/provider/challenge_data_source.go index a49fc00..306f142 100644 --- a/internal/provider/challenge/challenge_data_source.go +++ b/internal/provider/challenge_data_source.go @@ -1,14 +1,16 @@ -package challenge +package provider import ( "context" "fmt" "strconv" - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/pandatix/go-ctfd/api" + "github.com/ctfer-io/go-ctfd/api" + "github.com/ctfer-io/terraform-provider-ctfd/internal/provider/challenge" + "github.com/ctfer-io/terraform-provider-ctfd/internal/provider/utils" + "github.com/opentofu/terraform-plugin-framework/datasource" + "github.com/opentofu/terraform-plugin-framework/datasource/schema" + "github.com/opentofu/terraform-plugin-framework/types" ) var ( @@ -25,6 +27,7 @@ type challengeDataSource struct { } type challengesDataSourceModel struct { + ID types.String `tfsdk:"id"` Challenges []challengeResourceModel `tfsdk:"challenges"` } @@ -35,6 +38,9 @@ func (ch *challengeDataSource) Metadata(ctx context.Context, req datasource.Meta func (ch *challengeDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, "challenges": schema.ListNestedAttribute{ Computed: true, NestedObject: schema.NestedAttributeObject{ @@ -71,7 +77,7 @@ func (ch *challengeDataSource) Schema(ctx context.Context, req datasource.Schema }, "flags": schema.ListNestedAttribute{ NestedObject: schema.NestedAttributeObject{ - Attributes: flagSubdatasourceAttributes(), + Attributes: challenge.FlagSubdatasourceAttributes(), }, Computed: true, }, @@ -85,13 +91,13 @@ func (ch *challengeDataSource) Schema(ctx context.Context, req datasource.Schema }, "hints": schema.ListNestedAttribute{ NestedObject: schema.NestedAttributeObject{ - Attributes: hintSubdatasourceAttributes(), + Attributes: challenge.HintSubdatasourceAttributes(), }, Computed: true, }, "files": schema.ListNestedAttribute{ NestedObject: schema.NestedAttributeObject{ - Attributes: fileSubdatasourceAttributes(), + Attributes: challenge.FileSubdatasourceAttributes(), }, Computed: true, }, @@ -111,7 +117,7 @@ func (ch *challengeDataSource) Configure(ctx context.Context, req datasource.Con if !ok { resp.Diagnostics.AddError( "Unexpected Data Source Configure Type", - fmt.Sprintf("Expected *github.com/pandatix/go-ctfd/api.Client, got: %T. Please open an issue at https://github.com/pandatix/terraform-provider-ctfd", req.ProviderData), + fmt.Sprintf("Expected *github.com/ctfer-io/go-ctfd/api.Client, got: %T. Please open an issue at https://github.com/ctfer-io/terraform-provider-ctfd", req.ProviderData), ) return } @@ -151,9 +157,9 @@ func (ch *challengeDataSource) Read(ctx context.Context, req datasource.ReadRequ ) return } - challFiles := make([]fileSubresourceModel, 0, len(files)) + challFiles := make([]challenge.FileSubresourceModel, 0, len(files)) for _, file := range files { - f := fileSubresourceModel{ + f := challenge.FileSubresourceModel{ ID: types.StringValue(strconv.Itoa(file.ID)), Location: types.StringValue(file.Location), } @@ -171,9 +177,9 @@ func (ch *challengeDataSource) Read(ctx context.Context, req datasource.ReadRequ ) return } - challFlags := make([]flagSubresourceModel, 0, len(flags)) + challFlags := make([]challenge.FlagSubresourceModel, 0, len(flags)) for _, flag := range flags { - challFlags = append(challFlags, flagSubresourceModel{ + challFlags = append(challFlags, challenge.FlagSubresourceModel{ ID: types.StringValue(strconv.Itoa(flag.ID)), Content: types.StringValue(flag.Content), // XXX this should be properly typed @@ -219,13 +225,13 @@ func (ch *challengeDataSource) Read(ctx context.Context, req datasource.ReadRequ ) return } - challHints := make([]hintSubresourceModel, 0, len(hints)) + challHints := make([]challenge.HintSubresourceModel, 0, len(hints)) for _, hint := range hints { hintReq := make([]types.String, 0, len(hint.Requirements.Prerequisites)) for _, preq := range hint.Requirements.Prerequisites { hintReq = append(hintReq, types.StringValue(strconv.Itoa(preq))) } - challHints = append(challHints, hintSubresourceModel{ + challHints = append(challHints, challenge.HintSubresourceModel{ ID: types.StringValue(strconv.Itoa(hint.ID)), Content: types.StringValue(*hint.Content), Cost: types.Int64Value(int64(hint.Cost)), @@ -238,10 +244,10 @@ func (ch *challengeDataSource) Read(ctx context.Context, req datasource.ReadRequ Name: types.StringValue(chall.Name), Category: types.StringValue(chall.Category), Description: types.StringValue(chall.Description), - Value: toTFInt64(chall.Value), - Initial: toTFInt64(chall.Initial), - Decay: toTFInt64(chall.Decay), - Minimum: toTFInt64(chall.Minimum), + Value: utils.ToTFInt64(chall.Value), + Initial: utils.ToTFInt64(chall.Initial), + Decay: utils.ToTFInt64(chall.Decay), + Minimum: utils.ToTFInt64(chall.Minimum), State: types.StringValue(chall.State), Type: types.StringValue(chall.Type), Files: challFiles, @@ -251,6 +257,7 @@ func (ch *challengeDataSource) Read(ctx context.Context, req datasource.ReadRequ Hints: challHints, } + state.ID = types.StringValue("placeholder") state.Challenges = append(state.Challenges, challState) } diff --git a/internal/provider/challenge_data_source_test.go b/internal/provider/challenge_data_source_test.go new file mode 100644 index 0000000..1f19c69 --- /dev/null +++ b/internal/provider/challenge_data_source_test.go @@ -0,0 +1,20 @@ +package provider_test + +import ( + "testing" + + "github.com/opentofu/terraform-plugin-testing/helper/resource" +) + +func TestAccChallengeDataSource(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Read testing + { + Config: `data "ctfd_challenge" "test" {}`, + Check: resource.C, + }, + }, + }) +} diff --git a/internal/provider/challenge/challenge_resource.go b/internal/provider/challenge_resource.go similarity index 81% rename from internal/provider/challenge/challenge_resource.go rename to internal/provider/challenge_resource.go index 12ac68f..c2b8edc 100644 --- a/internal/provider/challenge/challenge_resource.go +++ b/internal/provider/challenge_resource.go @@ -1,23 +1,25 @@ -package challenge +package provider import ( "context" "fmt" "strconv" - "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/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" - "github.com/hashicorp/terraform-plugin-log/tflog" - api "github.com/pandatix/go-ctfd/api" - "github.com/pandatix/terraform-provider-ctfd/internal/provider/validators" + api "github.com/ctfer-io/go-ctfd/api" + "github.com/ctfer-io/terraform-provider-ctfd/internal/provider/challenge" + "github.com/ctfer-io/terraform-provider-ctfd/internal/provider/utils" + "github.com/ctfer-io/terraform-provider-ctfd/internal/provider/validators" + "github.com/opentofu/terraform-plugin-framework/path" + "github.com/opentofu/terraform-plugin-framework/resource" + "github.com/opentofu/terraform-plugin-framework/resource/schema" + "github.com/opentofu/terraform-plugin-framework/resource/schema/int64default" + "github.com/opentofu/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/opentofu/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/opentofu/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/opentofu/terraform-plugin-framework/schema/validator" + "github.com/opentofu/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-framework/types/basetypes" + "github.com/opentofu/terraform-plugin-log/tflog" ) var ( @@ -35,24 +37,24 @@ type challengeResource struct { } type challengeResourceModel struct { - ID types.String `tfsdk:"id"` - Name types.String `tfsdk:"name"` - Category types.String `tfsdk:"category"` - Description types.String `tfsdk:"description"` - ConnectionInfo types.String `tfsdk:"connection_info"` - MaxAttempts types.Int64 `tfsdk:"max_attempts"` - Value types.Int64 `tfsdk:"value"` - Initial types.Int64 `tfsdk:"initial"` - Decay types.Int64 `tfsdk:"decay"` - Minimum types.Int64 `tfsdk:"minimum"` - State types.String `tfsdk:"state"` - Type types.String `tfsdk:"type"` - Requirements *requirementsSubresourceModel `tfsdk:"requirements"` - Flags []flagSubresourceModel `tfsdk:"flags"` - Tags []types.String `tfsdk:"tags"` - Topics []types.String `tfsdk:"topics"` - Hints []hintSubresourceModel `tfsdk:"hints"` - Files []fileSubresourceModel `tfsdk:"files"` + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Category types.String `tfsdk:"category"` + Description types.String `tfsdk:"description"` + ConnectionInfo types.String `tfsdk:"connection_info"` + MaxAttempts types.Int64 `tfsdk:"max_attempts"` + Value types.Int64 `tfsdk:"value"` + Initial types.Int64 `tfsdk:"initial"` + Decay types.Int64 `tfsdk:"decay"` + Minimum types.Int64 `tfsdk:"minimum"` + State types.String `tfsdk:"state"` + Type types.String `tfsdk:"type"` + Requirements *challenge.RequirementsSubresourceModel `tfsdk:"requirements"` + Flags []challenge.FlagSubresourceModel `tfsdk:"flags"` + Tags []types.String `tfsdk:"tags"` + Topics []types.String `tfsdk:"topics"` + Hints []challenge.HintSubresourceModel `tfsdk:"hints"` + Files []challenge.FileSubresourceModel `tfsdk:"files"` } func (r *challengeResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { @@ -126,8 +128,8 @@ func (r *challengeResource) Schema(ctx context.Context, req resource.SchemaReque Default: stringdefault.StaticString("hidden"), Validators: []validator.String{ validators.NewStringEnumValidator([]basetypes.StringValue{ - behaviorHidden, - behaviorAnonymized, + challenge.BehaviorHidden, + challenge.BehaviorAnonymized, }), }, }, @@ -139,7 +141,7 @@ func (r *challengeResource) Schema(ctx context.Context, req resource.SchemaReque }, "flags": schema.ListNestedAttribute{ NestedObject: schema.NestedAttributeObject{ - Attributes: flagSubresourceAttributes(), + Attributes: challenge.FlagSubresourceAttributes(), }, Optional: true, }, @@ -153,14 +155,14 @@ func (r *challengeResource) Schema(ctx context.Context, req resource.SchemaReque }, "hints": schema.ListNestedAttribute{ NestedObject: schema.NestedAttributeObject{ - Attributes: hintSubresourceAttributes(), + Attributes: challenge.HintSubresourceAttributes(), }, Optional: true, }, "files": schema.ListNestedAttribute{ // TODO find why modifying other fields requires updating those NestedObject: schema.NestedAttributeObject{ - Attributes: fileSubresourceAttributes(), + Attributes: challenge.FileSubresourceAttributes(), }, Optional: true, }, @@ -178,7 +180,7 @@ func (r *challengeResource) Configure(ctx context.Context, req resource.Configur if !ok { resp.Diagnostics.AddError( "Unexpected Resource Configure Type", - fmt.Sprintf("Expected *github.com/pandatix/go-ctfd/api.Client, got: %T. Please open an issue at https://github.com/pandatix/terraform-provider-ctfd", req.ProviderData), + fmt.Sprintf("Expected *github.com/ctfer-io/go-ctfd/api.Client, got: %T. Please open an issue at https://github.com/ctfer-io/terraform-provider-ctfd", req.ProviderData), ) return } @@ -202,7 +204,7 @@ func (r *challengeResource) Create(ctx context.Context, req resource.CreateReque preqs = append(preqs, id) } reqs = &api.Requirements{ - Anonymize: getAnon(data.Requirements.Behavior), + Anonymize: challenge.GetAnon(data.Requirements.Behavior), Prerequisites: preqs, } } @@ -211,11 +213,11 @@ func (r *challengeResource) Create(ctx context.Context, req resource.CreateReque Category: data.Category.ValueString(), Description: data.Description.ValueString(), ConnectionInfo: data.ConnectionInfo.ValueStringPointer(), - MaxAttempts: toInt(data.MaxAttempts), - Value: toInt(data.Value), - Initial: toInt(data.Initial), - Decay: toInt(data.Decay), - Minimum: toInt(data.Minimum), + MaxAttempts: utils.ToInt(data.MaxAttempts), + Value: utils.ToInt(data.Value), + Initial: utils.ToInt(data.Initial), + Decay: utils.ToInt(data.Decay), + Minimum: utils.ToInt(data.Minimum), State: data.State.ValueString(), Type: data.Type.ValueString(), Requirements: reqs, @@ -234,7 +236,7 @@ func (r *challengeResource) Create(ctx context.Context, req resource.CreateReque data.ID = types.StringValue(strconv.Itoa(res.ID)) // Create files - challFiles := make([]fileSubresourceModel, 0, len(data.Files)) + challFiles := make([]challenge.FileSubresourceModel, 0, len(data.Files)) for _, file := range data.Files { file.Create(ctx, resp.Diagnostics, r.client, data.ID.ValueString()) challFiles = append(challFiles, file) @@ -244,7 +246,7 @@ func (r *challengeResource) Create(ctx context.Context, req resource.CreateReque } // Create flags - challFlags := make([]flagSubresourceModel, 0, len(data.Flags)) + challFlags := make([]challenge.FlagSubresourceModel, 0, len(data.Flags)) for _, flag := range data.Flags { flag.Create(ctx, resp.Diagnostics, r.client, data.ID.ValueString()) challFlags = append(challFlags, flag) @@ -295,7 +297,7 @@ func (r *challengeResource) Create(ctx context.Context, req resource.CreateReque } // Create hints - challHints := make([]hintSubresourceModel, 0, len(data.Hints)) + challHints := make([]challenge.HintSubresourceModel, 0, len(data.Hints)) for _, hint := range data.Hints { hint.Create(ctx, resp.Diagnostics, r.client, data.ID.ValueString()) challHints = append(challHints, hint) @@ -328,10 +330,10 @@ func (r *challengeResource) Read(ctx context.Context, req resource.ReadRequest, data.Description = types.StringValue(res.Description) data.ConnectionInfo = types.StringValue(res.ConnectionInfo) data.MaxAttempts = types.Int64Value(int64(res.MaxAttempts)) - data.Value = toTFInt64(res.Value) - data.Initial = toTFInt64(res.Initial) - data.Decay = toTFInt64(res.Decay) - data.Minimum = toTFInt64(res.Minimum) + data.Value = utils.ToTFInt64(res.Value) + data.Initial = utils.ToTFInt64(res.Initial) + data.Decay = utils.ToTFInt64(res.Decay) + data.Minimum = utils.ToTFInt64(res.Minimum) data.State = types.StringValue(res.State) data.Type = types.StringValue(res.Type) @@ -343,14 +345,14 @@ func (r *challengeResource) Read(ctx context.Context, req resource.ReadRequest, fmt.Sprintf("Unable to read requirements of challenge %s, got error: %s", data.ID.ValueString(), err), ) } - reqs := (*requirementsSubresourceModel)(nil) + reqs := (*challenge.RequirementsSubresourceModel)(nil) if resReqs != nil { challReqs := make([]types.String, 0, len(resReqs.Prerequisites)) for _, req := range resReqs.Prerequisites { challReqs = append(challReqs, types.StringValue(strconv.Itoa(req))) } - reqs = &requirementsSubresourceModel{ - Behavior: fromAnon(resReqs.Anonymize), + reqs = &challenge.RequirementsSubresourceModel{ + Behavior: challenge.FromAnon(resReqs.Anonymize), Prerequisites: challReqs, } } @@ -364,12 +366,12 @@ func (r *challengeResource) Read(ctx context.Context, req resource.ReadRequest, fmt.Sprintf("Unable to read files of challenge %s, got error: %s", data.ID.ValueString(), err), ) } - challFiles := make([]fileSubresourceModel, 0, len(resFiles)) + challFiles := make([]challenge.FileSubresourceModel, 0, len(resFiles)) for _, file := range resFiles { - f := fileSubresourceModel{ + f := challenge.FileSubresourceModel{ ID: types.StringValue(strconv.Itoa(file.ID)), Location: types.StringValue(file.Location), - Name: types.StringValue(filename(file.Location)), + Name: types.StringValue(utils.Filename(file.Location)), } f.Read(ctx, resp.Diagnostics, r.client) challFiles = append(challFiles, f) @@ -387,9 +389,9 @@ func (r *challengeResource) Read(ctx context.Context, req resource.ReadRequest, ) return } - challFlags := make([]flagSubresourceModel, 0, len(resFlags)) + challFlags := make([]challenge.FlagSubresourceModel, 0, len(resFlags)) for _, flag := range resFlags { - challFlags = append(challFlags, flagSubresourceModel{ + challFlags = append(challFlags, challenge.FlagSubresourceModel{ ID: types.StringValue(strconv.Itoa(flag.ID)), Content: types.StringValue(flag.Content), // XXX this should be typed properly @@ -444,7 +446,7 @@ func (r *challengeResource) Read(ctx context.Context, req resource.ReadRequest, ) return } - challHints := make([]hintSubresourceModel, 0, len(resHints)) + challHints := make([]challenge.HintSubresourceModel, 0, len(resHints)) for _, hint := range resHints { hintReqs := make([]types.String, 0, len(hint.Requirements.Prerequisites)) for _, req := range hint.Requirements.Prerequisites { @@ -453,7 +455,7 @@ func (r *challengeResource) Read(ctx context.Context, req resource.ReadRequest, if len(hint.Requirements.Prerequisites) == 0 { hintReqs = nil } - challHints = append(challHints, hintSubresourceModel{ + challHints = append(challHints, challenge.HintSubresourceModel{ ID: types.StringValue(strconv.Itoa(hint.ID)), Content: types.StringValue(*hint.Content), Cost: types.Int64Value(int64(hint.Cost)), @@ -488,7 +490,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque preqs = append(preqs, id) } reqs = &api.Requirements{ - Anonymize: getAnon(data.Requirements.Behavior), + Anonymize: challenge.GetAnon(data.Requirements.Behavior), Prerequisites: preqs, } } @@ -497,11 +499,11 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque Category: data.Category.ValueStringPointer(), Description: data.Description.ValueStringPointer(), ConnectionInfo: data.ConnectionInfo.ValueStringPointer(), - MaxAttempts: toInt(data.MaxAttempts), - Value: toInt(data.Value), - Initial: toInt(data.Initial), - Decay: toInt(data.Decay), - Minimum: toInt(data.Minimum), + MaxAttempts: utils.ToInt(data.MaxAttempts), + Value: utils.ToInt(data.Value), + Initial: utils.ToInt(data.Initial), + Decay: utils.ToInt(data.Decay), + Minimum: utils.ToInt(data.Minimum), State: data.State.ValueStringPointer(), Requirements: reqs, }, api.WithContext(ctx)) @@ -521,7 +523,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque fmt.Sprintf("Unable to get challenge's files, got error: %s", err), ) } - files := []fileSubresourceModel{} + files := []challenge.FileSubresourceModel{} for _, file := range data.Files { exists := false for _, currentFile := range currentFiles { @@ -529,7 +531,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque exists = true // Get corresponding file from state - var corFile fileSubresourceModel + var corFile challenge.FileSubresourceModel for _, fState := range dataState.Files { if file.ID.Equal(fState.ID) { corFile = fState @@ -562,7 +564,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque } } if !exists { - f := fileSubresourceModel{ + f := challenge.FileSubresourceModel{ ID: types.StringValue(strconv.Itoa(currentFile.ID)), Location: types.StringValue(currentFile.Location), } @@ -582,7 +584,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque ) return } - flags := []flagSubresourceModel{} + flags := []challenge.FlagSubresourceModel{} for _, tfFlag := range data.Flags { exists := false for _, currentFlag := range currentFlags { @@ -607,7 +609,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque } } if !exists { - f := &flagSubresourceModel{ + f := &challenge.FlagSubresourceModel{ ID: types.StringValue(strconv.Itoa(currentFlag.ID)), } f.Delete(ctx, resp.Diagnostics, r.client) @@ -701,7 +703,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque ) return } - hints := []hintSubresourceModel{} + hints := []challenge.HintSubresourceModel{} for _, tfHint := range data.Hints { exists := false for _, currentHint := range currentHints { @@ -726,7 +728,7 @@ func (r *challengeResource) Update(ctx context.Context, req resource.UpdateReque } } if !exists { - h := &hintSubresourceModel{ + h := &challenge.HintSubresourceModel{ ID: types.StringValue(strconv.Itoa(currentHint.ID)), } h.Delete(ctx, resp.Diagnostics, r.client) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5bb7bdd..b595b64 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -4,15 +4,14 @@ import ( "context" "os" - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/provider" - "github.com/hashicorp/terraform-plugin-framework/provider/schema" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/pandatix/go-ctfd/api" - "github.com/pandatix/terraform-provider-ctfd/internal/provider/challenge" + "github.com/ctfer-io/go-ctfd/api" + "github.com/opentofu/terraform-plugin-framework/datasource" + "github.com/opentofu/terraform-plugin-framework/path" + "github.com/opentofu/terraform-plugin-framework/provider" + "github.com/opentofu/terraform-plugin-framework/provider/schema" + "github.com/opentofu/terraform-plugin-framework/resource" + "github.com/opentofu/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-log/tflog" ) var _ provider.Provider = &CTFdProvider{} @@ -157,12 +156,12 @@ func (p *CTFdProvider) Configure(ctx context.Context, req provider.ConfigureRequ func (p *CTFdProvider) Resources(ctx context.Context) []func() resource.Resource { return []func() resource.Resource{ - challenge.NewChallengeResource, + NewChallengeResource, } } func (p *CTFdProvider) DataSources(ctx context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ - challenge.NewChallengeDataSource, + NewChallengeDataSource, } } diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go new file mode 100644 index 0000000..14a06ba --- /dev/null +++ b/internal/provider/provider_test.go @@ -0,0 +1,22 @@ +package provider_test + +import ( + "github.com/opentofu/terraform-plugin-framework/providerserver" + "github.com/opentofu/terraform-plugin-go/tfprotov6" +) + +const ( + providerConfig = ` +provider "ctfd" { + username = "never gonna give you up" + password = "never gonna let you down" + host = "https://example.ctfer.io" +} +` +) + +var ( + testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){ + "ctfd": providerserver.NewProtocol6WithError(New("test")()), + } +) diff --git a/internal/provider/utils.go b/internal/provider/utils.go index 7a5036f..a405489 100644 --- a/internal/provider/utils.go +++ b/internal/provider/utils.go @@ -3,7 +3,7 @@ package provider import ( "context" - "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/opentofu/terraform-plugin-log/tflog" ) func addSensitive(ctx context.Context, key string, value any) context.Context { diff --git a/internal/provider/challenge/utils.go b/internal/provider/utils/utils.go similarity index 64% rename from internal/provider/challenge/utils.go rename to internal/provider/utils/utils.go index 2713752..a02076f 100644 --- a/internal/provider/challenge/utils.go +++ b/internal/provider/utils/utils.go @@ -1,13 +1,13 @@ -package challenge +package utils import ( "strings" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-framework/types" ) // return a null types.Int64 if pointer is nil, else its value -func toTFInt64(i *int) types.Int64 { +func ToTFInt64(i *int) types.Int64 { if i == nil { return types.Int64Null() } @@ -15,7 +15,7 @@ func toTFInt64(i *int) types.Int64 { } // return a nil point if types.Int64 is null, else its value -func toInt(itf types.Int64) *int { +func ToInt(itf types.Int64) *int { if itf.IsNull() { return nil } @@ -23,11 +23,11 @@ func toInt(itf types.Int64) *int { return &i } -func filename(location string) string { +func Filename(location string) string { pts := strings.Split(location, "/") return pts[len(pts)-1] } -func ptr[T any](t T) *T { +func Ptr[T any](t T) *T { return &t } diff --git a/internal/provider/validators/string_enum.go b/internal/provider/validators/string_enum.go index a44ce87..111b490 100644 --- a/internal/provider/validators/string_enum.go +++ b/internal/provider/validators/string_enum.go @@ -3,8 +3,8 @@ package validators import ( "context" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/opentofu/terraform-plugin-framework/schema/validator" + "github.com/opentofu/terraform-plugin-framework/types" ) // StringEnumValidator valides a string value in an enumeration. diff --git a/main.go b/main.go index ed11643..5d0f453 100644 --- a/main.go +++ b/main.go @@ -5,8 +5,8 @@ import ( "flag" "log" - "github.com/hashicorp/terraform-plugin-framework/providerserver" - "github.com/pandatix/terraform-provider-ctfd/internal/provider" + "github.com/ctfer-io/terraform-provider-ctfd/internal/provider" + "github.com/opentofu/terraform-plugin-framework/providerserver" ) var ( @@ -20,7 +20,7 @@ func main() { flag.Parse() opts := providerserver.ServeOpts{ - Address: "registry.terraform.io/pandatix/ctfd", + Address: "registry.terraform.io/ctfer-io/ctfd", Debug: debug, }