├── .github ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── release.yml │ ├── tag.yaml │ └── test.yml ├── .gitignore ├── .goreleaser.yml ├── .vscode └── launch.json ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── docs ├── data-sources │ └── order.md ├── index.md └── resources │ ├── order.md │ └── pdf.md ├── examples ├── README.md ├── data-sources │ └── mailform_order │ │ └── data-source.tf ├── provider │ └── provider.tf └── resources │ ├── mailform_order │ └── order.tf │ └── mailform_pdf │ └── pdf.tf ├── go.mod ├── go.sum ├── internal └── provider │ ├── data_source_order.go │ ├── data_source_order_test.go │ ├── provider.go │ ├── provider_test.go │ ├── resource_order.go │ ├── resource_pdf.go │ └── resource_pdf_test.go ├── main.go ├── terraform-registry-manifest.json └── tools └── tools.go /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @hashicorp/terraform-devex 2 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | HashiCorp Community Guidelines apply to you when interacting with the community here on GitHub and contributing code. 4 | 5 | Please read the full text at https://www.hashicorp.com/community-guidelines 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Hi there, 2 | 3 | Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html. 4 | 5 | ### Terraform Version 6 | Run `terraform -v` to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed. 7 | 8 | ### Affected Resource(s) 9 | Please list the resources as a list, for example: 10 | - opc_instance 11 | - opc_storage_volume 12 | 13 | If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this. 14 | 15 | ### Terraform Configuration Files 16 | ```hcl 17 | # Copy-paste your Terraform configurations here - for large Terraform configs, 18 | # please use a service like Dropbox and share a link to the ZIP file. For 19 | # security, you can also encrypt the files using our GPG public key. 20 | ``` 21 | 22 | ### Debug Output 23 | Please provider a link to a GitHub Gist containing the complete debug output: https://www.terraform.io/docs/internals/debugging.html. Please do NOT paste the debug output in the issue; just paste a link to the Gist. 24 | 25 | ### Panic Output 26 | If Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the `crash.log`. 27 | 28 | ### Expected Behavior 29 | What should have happened? 30 | 31 | ### Actual Behavior 32 | What actually happened? 33 | 34 | ### Steps to Reproduce 35 | Please list the steps required to reproduce the issue, for example: 36 | 1. `terraform apply` 37 | 38 | ### Important Factoids 39 | Are there anything atypical about your accounts that we should know? For example: Running in EC2 Classic? Custom version of OpenStack? Tight ACLs? 40 | 41 | ### References 42 | Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example: 43 | - GH-1234 44 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See GitHub's docs for more information on this file: 2 | # https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates 3 | version: 2 4 | updates: 5 | # Maintain dependencies for GitHub Actions 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | # Check for updates to GitHub Actions every weekday 10 | interval: "daily" 11 | 12 | # Maintain dependencies for Go modules 13 | - package-ecosystem: "gomod" 14 | directory: "/" 15 | schedule: 16 | # Check for updates to Go modules every weekday 17 | interval: "daily" 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # This GitHub action can publish assets for release when a tag is created. 2 | # Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). 3 | # 4 | # This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your 5 | # private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` 6 | # secret. If you would rather own your own GPG handling, please fork this action 7 | # or use an alternative one for key handling. 8 | # 9 | # You will need to pass the `--batch` flag to `gpg` in your signing step 10 | # in `goreleaser` to indicate this is being used in a non-interactive mode. 11 | # 12 | name: release 13 | on: 14 | workflow_run: 15 | workflows: ["Bump Git Version"] 16 | branches: [main] 17 | types: 18 | - completed 19 | permissions: 20 | contents: write 21 | jobs: 22 | goreleaser: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v3 27 | - name: Unshallow 28 | run: git fetch --prune --unshallow 29 | - name: Set up Go 30 | uses: actions/setup-go@v3 31 | - name: Import GPG key 32 | uses: crazy-max/ghaction-import-gpg@v5 33 | id: import_gpg 34 | with: 35 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} 36 | passphrase: ${{ secrets.PASSPHRASE }} 37 | - name: Run GoReleaser 38 | uses: goreleaser/goreleaser-action@v3.2.0 39 | with: 40 | version: latest 41 | args: release --rm-dist 42 | env: 43 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 44 | # GitHub sets this automatically 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | - name: GoReportCard 47 | uses: creekorful/goreportcard-action@v1.0 48 | -------------------------------------------------------------------------------- /.github/workflows/tag.yaml: -------------------------------------------------------------------------------- 1 | name: Bump Git Version 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | semver: 8 | runs-on: ubuntu-latest 9 | outputs: 10 | tag: ${{ steps.tagging.outputs.new_tag }} 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | fetch-depth: '0' 15 | - name: Bump version and push tag 16 | uses: anothrNick/github-tag-action@1.61.0 17 | id: tagging 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | WITH_V: true 21 | RELEASE_BRANCHES: main 22 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # This GitHub action runs your tests for each commit push and/or PR. Optionally 2 | # you can turn it on using a cron schedule for regular testing. 3 | # 4 | name: Tests 5 | on: 6 | pull_request: 7 | paths-ignore: 8 | - 'README.md' 9 | push: 10 | paths-ignore: 11 | - 'README.md' 12 | # For systems with an upstream API that could drift unexpectedly (like most SaaS systems, etc.), 13 | # we recommend testing at a regular interval not necessarily tied to code changes. This will 14 | # ensure you are alerted to something breaking due to an API change, even if the code did not 15 | # change. 16 | # schedule: 17 | # - cron: '0 13 * * *' 18 | jobs: 19 | # ensure the code builds... 20 | build: 21 | name: Build 22 | runs-on: ubuntu-latest 23 | timeout-minutes: 5 24 | steps: 25 | 26 | - name: Check out code into the Go module directory 27 | uses: actions/checkout@v3 28 | 29 | - name: Set up Go 30 | uses: actions/setup-go@v3 31 | id: go 32 | 33 | - name: Get dependencies 34 | run: | 35 | go mod download 36 | 37 | - name: Build 38 | run: | 39 | go build -v . 40 | 41 | generate: 42 | runs-on: ubuntu-latest 43 | steps: 44 | - uses: actions/checkout@v3 45 | - uses: actions/setup-go@v3 46 | - run: go generate ./... 47 | - name: git diff 48 | run: | 49 | git diff --compact-summary --exit-code || \ 50 | (echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1) 51 | 52 | # run acceptance tests in a matrix with Terraform core versions 53 | test: 54 | name: Matrix Test 55 | needs: build 56 | runs-on: ubuntu-latest 57 | timeout-minutes: 15 58 | strategy: 59 | fail-fast: false 60 | matrix: 61 | # list whatever Terraform versions here you would like to support 62 | terraform: 63 | - '0.12.*' 64 | - '0.13.*' 65 | - '0.14.*' 66 | - '0.15.*' 67 | - '1.0.*' 68 | - '1.1.*' 69 | - '1.2.*' 70 | - '1.3.*' 71 | steps: 72 | 73 | - name: Check out code into the Go module directory 74 | uses: actions/checkout@v3 75 | 76 | - name: Set up Go 77 | uses: actions/setup-go@v3 78 | id: go 79 | 80 | - uses: hashicorp/setup-terraform@v2 81 | with: 82 | terraform_version: ${{ matrix.terraform }} 83 | terraform_wrapper: false 84 | 85 | - name: Get dependencies 86 | run: | 87 | go mod download 88 | 89 | - name: TF acceptance tests 90 | timeout-minutes: 10 91 | env: 92 | TF_ACC: "1" 93 | 94 | # Set whatever additional acceptance test env vars here. You can 95 | # optionally use data from your repository secrets using the 96 | # following syntax: 97 | # SOME_VAR: ${{ secrets.SOME_VAR }} 98 | 99 | run: | 100 | go test -v -cover ./internal/provider/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | .DS_Store 4 | example.tf 5 | terraform.tfplan 6 | terraform.tfstate 7 | bin/ 8 | dist/ 9 | modules-dev/ 10 | /pkg/ 11 | website/.vagrant 12 | website/.bundle 13 | website/build 14 | website/node_modules 15 | .vagrant/ 16 | *.backup 17 | ./*.tfstate 18 | .terraform/ 19 | *.log 20 | *.bak 21 | *~ 22 | .*.swp 23 | .idea 24 | *.iml 25 | *.test 26 | *.iml 27 | 28 | website/vendor 29 | 30 | # Test exclusions 31 | !command/test-fixtures/**/*.tfstate 32 | !command/test-fixtures/**/.terraform/ 33 | 34 | # Keep windows files with windows line endings 35 | *.winfile eol=crlf 36 | 37 | # ze tf 38 | .terraform.local.hcl 39 | *tfstate* 40 | .terraform/ 41 | .terraform.lock.hcl 42 | 43 | # bs pdfs 44 | *.pdf 45 | 46 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # Visit https://goreleaser.com for documentation on how to customize this 2 | # behavior. 3 | before: 4 | hooks: 5 | # this is just an example and not a requirement for provider building/publishing 6 | - go mod tidy 7 | builds: 8 | - env: 9 | # goreleaser does not work with CGO, it could also complicate 10 | # usage by users in CI/CD systems like Terraform Cloud where 11 | # they are unable to install libraries. 12 | - CGO_ENABLED=0 13 | mod_timestamp: '{{ .CommitTimestamp }}' 14 | flags: 15 | - -trimpath 16 | ldflags: 17 | - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' 18 | goos: 19 | - freebsd 20 | - windows 21 | - linux 22 | - darwin 23 | goarch: 24 | - amd64 25 | - '386' 26 | - arm 27 | - arm64 28 | ignore: 29 | - goos: darwin 30 | goarch: '386' 31 | binary: '{{ .ProjectName }}_v{{ .Version }}' 32 | archives: 33 | - format: zip 34 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' 35 | checksum: 36 | extra_files: 37 | - glob: 'terraform-registry-manifest.json' 38 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 39 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' 40 | algorithm: sha256 41 | signs: 42 | - artifacts: checksum 43 | args: 44 | # if you are using this in a GitHub action or some other automated pipeline, you 45 | # need to pass the batch flag to indicate its not interactive. 46 | - "--batch" 47 | - "--local-user" 48 | - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key 49 | - "--output" 50 | - "${signature}" 51 | - "--detach-sign" 52 | - "${artifact}" 53 | release: 54 | extra_files: 55 | - glob: 'terraform-registry-manifest.json' 56 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 57 | # If you want to manually examine the release before its live, uncomment this line: 58 | # draft: true 59 | changelog: 60 | skip: true 61 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Acceptance Tests", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "test", 12 | // this assumes your workspace is the root of the repo 13 | "program": "${fileDirname}", 14 | "env": { 15 | "TF_ACC": "1", 16 | }, 17 | "args": [], 18 | }, 19 | { 20 | "name": "Debug - Attach External CLI", 21 | "type": "go", 22 | "request": "launch", 23 | "mode": "debug", 24 | // this assumes your workspace is the root of the repo 25 | "program": "${workspaceFolder}", 26 | "env": {}, 27 | "args": [ 28 | // pass the debug flag for reattaching 29 | "-debug", 30 | ], 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 (Unreleased) 2 | 3 | BACKWARDS INCOMPATIBILITIES / NOTES: 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 HashiCorp, Inc. 2 | 3 | Mozilla Public License Version 2.0 4 | ================================== 5 | 6 | 1. Definitions 7 | -------------- 8 | 9 | 1.1. "Contributor" 10 | means each individual or legal entity that creates, contributes to 11 | the creation of, or owns Covered Software. 12 | 13 | 1.2. "Contributor Version" 14 | means the combination of the Contributions of others (if any) used 15 | by a Contributor and that particular Contributor's Contribution. 16 | 17 | 1.3. "Contribution" 18 | means Covered Software of a particular Contributor. 19 | 20 | 1.4. "Covered Software" 21 | means Source Code Form to which the initial Contributor has attached 22 | the notice in Exhibit A, the Executable Form of such Source Code 23 | Form, and Modifications of such Source Code Form, in each case 24 | including portions thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | (a) that the initial Contributor has attached the notice described 30 | in Exhibit B to the Covered Software; or 31 | 32 | (b) that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the 34 | terms of a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | means any form of the work other than Source Code Form. 38 | 39 | 1.7. "Larger Work" 40 | means a work that combines Covered Software with other material, in 41 | a separate file or files, that is not Covered Software. 42 | 43 | 1.8. "License" 44 | means this document. 45 | 46 | 1.9. "Licensable" 47 | means having the right to grant, to the maximum extent possible, 48 | whether at the time of the initial grant or subsequently, any and 49 | all of the rights conveyed by this License. 50 | 51 | 1.10. "Modifications" 52 | means any of the following: 53 | 54 | (a) any file in Source Code Form that results from an addition to, 55 | deletion from, or modification of the contents of Covered 56 | Software; or 57 | 58 | (b) any new file in Source Code Form that contains any Covered 59 | Software. 60 | 61 | 1.11. "Patent Claims" of a Contributor 62 | means any patent claim(s), including without limitation, method, 63 | process, and apparatus claims, in any patent Licensable by such 64 | Contributor that would be infringed, but for the grant of the 65 | License, by the making, using, selling, offering for sale, having 66 | made, import, or transfer of either its Contributions or its 67 | Contributor Version. 68 | 69 | 1.12. "Secondary License" 70 | means either the GNU General Public License, Version 2.0, the GNU 71 | Lesser General Public License, Version 2.1, the GNU Affero General 72 | Public License, Version 3.0, or any later versions of those 73 | licenses. 74 | 75 | 1.13. "Source Code Form" 76 | means the form of the work preferred for making modifications. 77 | 78 | 1.14. "You" (or "Your") 79 | means an individual or a legal entity exercising rights under this 80 | License. For legal entities, "You" includes any entity that 81 | controls, is controlled by, or is under common control with You. For 82 | purposes of this definition, "control" means (a) the power, direct 83 | or indirect, to cause the direction or management of such entity, 84 | whether by contract or otherwise, or (b) ownership of more than 85 | fifty percent (50%) of the outstanding shares or beneficial 86 | ownership of such entity. 87 | 88 | 2. License Grants and Conditions 89 | -------------------------------- 90 | 91 | 2.1. Grants 92 | 93 | Each Contributor hereby grants You a world-wide, royalty-free, 94 | non-exclusive license: 95 | 96 | (a) under intellectual property rights (other than patent or trademark) 97 | Licensable by such Contributor to use, reproduce, make available, 98 | modify, display, perform, distribute, and otherwise exploit its 99 | Contributions, either on an unmodified basis, with Modifications, or 100 | as part of a Larger Work; and 101 | 102 | (b) under Patent Claims of such Contributor to make, use, sell, offer 103 | for sale, have made, import, and otherwise transfer either its 104 | Contributions or its Contributor Version. 105 | 106 | 2.2. Effective Date 107 | 108 | The licenses granted in Section 2.1 with respect to any Contribution 109 | become effective for each Contribution on the date the Contributor first 110 | distributes such Contribution. 111 | 112 | 2.3. Limitations on Grant Scope 113 | 114 | The licenses granted in this Section 2 are the only rights granted under 115 | this License. No additional rights or licenses will be implied from the 116 | distribution or licensing of Covered Software under this License. 117 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 118 | Contributor: 119 | 120 | (a) for any code that a Contributor has removed from Covered Software; 121 | or 122 | 123 | (b) for infringements caused by: (i) Your and any other third party's 124 | modifications of Covered Software, or (ii) the combination of its 125 | Contributions with other software (except as part of its Contributor 126 | Version); or 127 | 128 | (c) under Patent Claims infringed by Covered Software in the absence of 129 | its Contributions. 130 | 131 | This License does not grant any rights in the trademarks, service marks, 132 | or logos of any Contributor (except as may be necessary to comply with 133 | the notice requirements in Section 3.4). 134 | 135 | 2.4. Subsequent Licenses 136 | 137 | No Contributor makes additional grants as a result of Your choice to 138 | distribute the Covered Software under a subsequent version of this 139 | License (see Section 10.2) or under the terms of a Secondary License (if 140 | permitted under the terms of Section 3.3). 141 | 142 | 2.5. Representation 143 | 144 | Each Contributor represents that the Contributor believes its 145 | Contributions are its original creation(s) or it has sufficient rights 146 | to grant the rights to its Contributions conveyed by this License. 147 | 148 | 2.6. Fair Use 149 | 150 | This License is not intended to limit any rights You have under 151 | applicable copyright doctrines of fair use, fair dealing, or other 152 | equivalents. 153 | 154 | 2.7. Conditions 155 | 156 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 157 | in Section 2.1. 158 | 159 | 3. Responsibilities 160 | ------------------- 161 | 162 | 3.1. Distribution of Source Form 163 | 164 | All distribution of Covered Software in Source Code Form, including any 165 | Modifications that You create or to which You contribute, must be under 166 | the terms of this License. You must inform recipients that the Source 167 | Code Form of the Covered Software is governed by the terms of this 168 | License, and how they can obtain a copy of this License. You may not 169 | attempt to alter or restrict the recipients' rights in the Source Code 170 | Form. 171 | 172 | 3.2. Distribution of Executable Form 173 | 174 | If You distribute Covered Software in Executable Form then: 175 | 176 | (a) such Covered Software must also be made available in Source Code 177 | Form, as described in Section 3.1, and You must inform recipients of 178 | the Executable Form how they can obtain a copy of such Source Code 179 | Form by reasonable means in a timely manner, at a charge no more 180 | than the cost of distribution to the recipient; and 181 | 182 | (b) You may distribute such Executable Form under the terms of this 183 | License, or sublicense it under different terms, provided that the 184 | license for the Executable Form does not attempt to limit or alter 185 | the recipients' rights in the Source Code Form under this License. 186 | 187 | 3.3. Distribution of a Larger Work 188 | 189 | You may create and distribute a Larger Work under terms of Your choice, 190 | provided that You also comply with the requirements of this License for 191 | the Covered Software. If the Larger Work is a combination of Covered 192 | Software with a work governed by one or more Secondary Licenses, and the 193 | Covered Software is not Incompatible With Secondary Licenses, this 194 | License permits You to additionally distribute such Covered Software 195 | under the terms of such Secondary License(s), so that the recipient of 196 | the Larger Work may, at their option, further distribute the Covered 197 | Software under the terms of either this License or such Secondary 198 | License(s). 199 | 200 | 3.4. Notices 201 | 202 | You may not remove or alter the substance of any license notices 203 | (including copyright notices, patent notices, disclaimers of warranty, 204 | or limitations of liability) contained within the Source Code Form of 205 | the Covered Software, except that You may alter any license notices to 206 | the extent required to remedy known factual inaccuracies. 207 | 208 | 3.5. Application of Additional Terms 209 | 210 | You may choose to offer, and to charge a fee for, warranty, support, 211 | indemnity or liability obligations to one or more recipients of Covered 212 | Software. However, You may do so only on Your own behalf, and not on 213 | behalf of any Contributor. You must make it absolutely clear that any 214 | such warranty, support, indemnity, or liability obligation is offered by 215 | You alone, and You hereby agree to indemnify every Contributor for any 216 | liability incurred by such Contributor as a result of warranty, support, 217 | indemnity or liability terms You offer. You may include additional 218 | disclaimers of warranty and limitations of liability specific to any 219 | jurisdiction. 220 | 221 | 4. Inability to Comply Due to Statute or Regulation 222 | --------------------------------------------------- 223 | 224 | If it is impossible for You to comply with any of the terms of this 225 | License with respect to some or all of the Covered Software due to 226 | statute, judicial order, or regulation then You must: (a) comply with 227 | the terms of this License to the maximum extent possible; and (b) 228 | describe the limitations and the code they affect. Such description must 229 | be placed in a text file included with all distributions of the Covered 230 | Software under this License. Except to the extent prohibited by statute 231 | or regulation, such description must be sufficiently detailed for a 232 | recipient of ordinary skill to be able to understand it. 233 | 234 | 5. Termination 235 | -------------- 236 | 237 | 5.1. The rights granted under this License will terminate automatically 238 | if You fail to comply with any of its terms. However, if You become 239 | compliant, then the rights granted under this License from a particular 240 | Contributor are reinstated (a) provisionally, unless and until such 241 | Contributor explicitly and finally terminates Your grants, and (b) on an 242 | ongoing basis, if such Contributor fails to notify You of the 243 | non-compliance by some reasonable means prior to 60 days after You have 244 | come back into compliance. Moreover, Your grants from a particular 245 | Contributor are reinstated on an ongoing basis if such Contributor 246 | notifies You of the non-compliance by some reasonable means, this is the 247 | first time You have received notice of non-compliance with this License 248 | from such Contributor, and You become compliant prior to 30 days after 249 | Your receipt of the notice. 250 | 251 | 5.2. If You initiate litigation against any entity by asserting a patent 252 | infringement claim (excluding declaratory judgment actions, 253 | counter-claims, and cross-claims) alleging that a Contributor Version 254 | directly or indirectly infringes any patent, then the rights granted to 255 | You by any and all Contributors for the Covered Software under Section 256 | 2.1 of this License shall terminate. 257 | 258 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 259 | end user license agreements (excluding distributors and resellers) which 260 | have been validly granted by You or Your distributors under this License 261 | prior to termination shall survive termination. 262 | 263 | ************************************************************************ 264 | * * 265 | * 6. Disclaimer of Warranty * 266 | * ------------------------- * 267 | * * 268 | * Covered Software is provided under this License on an "as is" * 269 | * basis, without warranty of any kind, either expressed, implied, or * 270 | * statutory, including, without limitation, warranties that the * 271 | * Covered Software is free of defects, merchantable, fit for a * 272 | * particular purpose or non-infringing. The entire risk as to the * 273 | * quality and performance of the Covered Software is with You. * 274 | * Should any Covered Software prove defective in any respect, You * 275 | * (not any Contributor) assume the cost of any necessary servicing, * 276 | * repair, or correction. This disclaimer of warranty constitutes an * 277 | * essential part of this License. No use of any Covered Software is * 278 | * authorized under this License except under this disclaimer. * 279 | * * 280 | ************************************************************************ 281 | 282 | ************************************************************************ 283 | * * 284 | * 7. Limitation of Liability * 285 | * -------------------------- * 286 | * * 287 | * Under no circumstances and under no legal theory, whether tort * 288 | * (including negligence), contract, or otherwise, shall any * 289 | * Contributor, or anyone who distributes Covered Software as * 290 | * permitted above, be liable to You for any direct, indirect, * 291 | * special, incidental, or consequential damages of any character * 292 | * including, without limitation, damages for lost profits, loss of * 293 | * goodwill, work stoppage, computer failure or malfunction, or any * 294 | * and all other commercial damages or losses, even if such party * 295 | * shall have been informed of the possibility of such damages. This * 296 | * limitation of liability shall not apply to liability for death or * 297 | * personal injury resulting from such party's negligence to the * 298 | * extent applicable law prohibits such limitation. Some * 299 | * jurisdictions do not allow the exclusion or limitation of * 300 | * incidental or consequential damages, so this exclusion and * 301 | * limitation may not apply to You. * 302 | * * 303 | ************************************************************************ 304 | 305 | 8. Litigation 306 | ------------- 307 | 308 | Any litigation relating to this License may be brought only in the 309 | courts of a jurisdiction where the defendant maintains its principal 310 | place of business and such litigation shall be governed by laws of that 311 | jurisdiction, without reference to its conflict-of-law provisions. 312 | Nothing in this Section shall prevent a party's ability to bring 313 | cross-claims or counter-claims. 314 | 315 | 9. Miscellaneous 316 | ---------------- 317 | 318 | This License represents the complete agreement concerning the subject 319 | matter hereof. If any provision of this License is held to be 320 | unenforceable, such provision shall be reformed only to the extent 321 | necessary to make it enforceable. Any law or regulation which provides 322 | that the language of a contract shall be construed against the drafter 323 | shall not be used to construe this License against a Contributor. 324 | 325 | 10. Versions of the License 326 | --------------------------- 327 | 328 | 10.1. New Versions 329 | 330 | Mozilla Foundation is the license steward. Except as provided in Section 331 | 10.3, no one other than the license steward has the right to modify or 332 | publish new versions of this License. Each version will be given a 333 | distinguishing version number. 334 | 335 | 10.2. Effect of New Versions 336 | 337 | You may distribute the Covered Software under the terms of the version 338 | of the License under which You originally received the Covered Software, 339 | or under the terms of any subsequent version published by the license 340 | steward. 341 | 342 | 10.3. Modified Versions 343 | 344 | If you create software not governed by this License, and you want to 345 | create a new license for such software, you may create and use a 346 | modified version of this License if you rename the license and remove 347 | any references to the name of the license steward (except to note that 348 | such modified license differs from this License). 349 | 350 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 351 | Licenses 352 | 353 | If You choose to distribute Source Code Form that is Incompatible With 354 | Secondary Licenses under the terms of this version of the License, the 355 | notice described in Exhibit B of this License must be attached. 356 | 357 | Exhibit A - Source Code Form License Notice 358 | ------------------------------------------- 359 | 360 | This Source Code Form is subject to the terms of the Mozilla Public 361 | License, v. 2.0. If a copy of the MPL was not distributed with this 362 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 363 | 364 | If it is not possible or desirable to put the notice in a particular 365 | file, then You may include the notice in a location (such as a LICENSE 366 | file in a relevant directory) where a recipient would be likely to look 367 | for such a notice. 368 | 369 | You may add additional accurate notices of copyright ownership. 370 | 371 | Exhibit B - "Incompatible With Secondary Licenses" Notice 372 | --------------------------------------------------------- 373 | 374 | This Source Code Form is "Incompatible With Secondary Licenses", as 375 | defined by the Mozilla Public License, v. 2.0. 376 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TEST?=$$(go list ./... | grep -v 'vendor') 2 | HOSTNAME=github.com 3 | NAMESPACE=circa10a 4 | NAME=mailform 5 | BINARY=terraform-provider-${NAME} 6 | VERSION=0.4.0 7 | OS_ARCH=darwin_amd64 8 | 9 | default: install 10 | 11 | build: 12 | go build -o ${BINARY} 13 | 14 | release: 15 | GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64 16 | GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386 17 | GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64 18 | GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm 19 | GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386 20 | GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64 21 | GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm 22 | GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386 23 | GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64 24 | GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64 25 | GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386 26 | GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64 27 | 28 | install: build 29 | mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} 30 | mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} 31 | 32 | test: 33 | go test $(TEST) || exit 1 34 | echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 35 | 36 | testacc: 37 | TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-provider-mailform 2 | 3 | This provider enables you to send physical mail, driven by terraform, via https://mailform.io 4 | 5 | Standing on the shoulders of giants enables us to yeet mail further. 6 | 7 | ![Build Status](https://github.com/circa10a/terraform-provider-mailform/workflows/release/badge.svg) 8 | [![Go Report Card](https://goreportcard.com/badge/github.com/circa10a/terraform-provider-mailform)](https://goreportcard.com/report/github.com/circa10a/terraform-provider-mailform) 9 | ![GitHub release (latest by date)](https://img.shields.io/github/v/release/circa10a/terraform-provider-mailform?style=plastic) 10 | [![Buy Me A Coffee](https://img.shields.io/badge/BuyMeACoffee-Donate-ff813f.svg?logo=CoffeeScript&style=plastic)](https://www.buymeacoffee.com/caleblemoine) 11 | 12 | > :warning: Orders cannot be updated/deleted (cancelled). Once created,no more modifications can be made due to API limitations. Deleted resources are simply removed from state. 13 | 14 | ## Usage 15 | 16 | The provider with use the environment variable `MAILFORM_API_TOKEN` by default unless specified in the provider configuration. 17 | 18 | ```hcl 19 | terraform { 20 | required_providers { 21 | mailform = { 22 | source = "circa10a/mailform" 23 | } 24 | } 25 | } 26 | 27 | provider "mailform" { 28 | api_token = "XXX" // If not specified, will read MAILFORM_API_TOKEN environment variable 29 | } 30 | 31 | // Create PDF 32 | resource "mailform_pdf" "example" { 33 | header = "My Resumes" 34 | content = "Some resume contents" 35 | filename = "./test.pdf" 36 | } 37 | 38 | // Convert image to pdf for postcards 39 | resource "mailform_pdf" "example" { 40 | image_filename = "./test_image.jpg" 41 | filename = "./test_image.pdf" 42 | } 43 | 44 | // Create mail order 45 | resource "mailform_order" "example" { 46 | pdf_file = mailform_pdf.example.filename 47 | service = "USPS_PRIORITY" 48 | to_name = "A name" 49 | to_address_1 = "Address 1" 50 | to_city = "Seattle" 51 | to_state = "WA" 52 | to_postcode = "00000" 53 | to_country = "US" 54 | from_name = "My name" 55 | from_address_1 = "My Address 1" 56 | from_city = "Dallas" 57 | from_state = "TX" 58 | from_postcode = "00000" 59 | from_country = "US" 60 | } 61 | 62 | // Fetch order data 63 | data "mailform_order" "example" { 64 | id = mailform_order.example.id 65 | } 66 | 67 | output "order_info" { 68 | value = data.mailform_order.example 69 | } 70 | ``` 71 | 72 | ## Requirements 73 | 74 | - [Terraform](https://www.terraform.io/downloads.html) >= 0.12.x 75 | - [Go](https://golang.org/doc/install) >= 1.18 76 | 77 | ## Building The Provider 78 | 79 | 1. Clone the repository 80 | 1. Enter the repository directory 81 | 1. Build the provider using the Go `install` command: 82 | 83 | ```sh 84 | go install 85 | ``` 86 | 87 | ## Adding Dependencies 88 | 89 | This provider uses [Go modules](https://github.com/golang/go/wiki/Modules). 90 | Please see the Go documentation for the most up to date information about using Go modules. 91 | 92 | To add a new dependency `github.com/author/dependency` to your Terraform provider: 93 | 94 | ```sh 95 | go get github.com/author/dependency 96 | go mod tidy 97 | ``` 98 | 99 | Then commit the changes to `go.mod` and `go.sum`. 100 | 101 | ## Using the provider 102 | 103 | Fill this in for each provider 104 | 105 | ## Developing the Provider 106 | 107 | If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above). 108 | 109 | To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory. 110 | 111 | To generate or update documentation, run `go generate`. 112 | -------------------------------------------------------------------------------- /docs/data-sources/order.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "mailform_order Data Source - terraform-provider-mailform" 4 | subcategory: "" 5 | description: |- 6 | Order data source in the Terraform provider mailform. 7 | --- 8 | 9 | # mailform_order (Data Source) 10 | 11 | Order data source in the Terraform provider mailform. 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | terraform { 17 | required_providers { 18 | mailform = { 19 | source = "circa10a/mailform" 20 | } 21 | } 22 | } 23 | 24 | data "mailform_order" "sample_order" { 25 | id = "foo" 26 | } 27 | 28 | output "order_info" { 29 | value = data.mailform_order.sample_order 30 | } 31 | ``` 32 | 33 | 34 | ## Schema 35 | 36 | ### Read-Only 37 | 38 | - `account` (String) 39 | - `cancellation_reason` (String) 40 | - `cancelled` (String) 41 | - `channel` (String) 42 | - `created` (String) 43 | - `customer_reference` (String) 44 | - `id` (String) The ID of this resource. 45 | - `lineitems` (List of Object) (see [below for nested schema](#nestedatt--lineitems)) 46 | - `modified` (String) 47 | - `object` (String) 48 | - `state` (String) 49 | - `test_mode` (Boolean) 50 | - `total` (Number) 51 | - `webhook` (String) 52 | 53 | 54 | ### Nested Schema for `lineitems` 55 | 56 | Read-Only: 57 | 58 | - `color` (Boolean) 59 | - `from_address_1` (String) 60 | - `from_address_2` (String) 61 | - `from_city` (String) 62 | - `from_country` (String) 63 | - `from_formatted` (String) 64 | - `from_name` (String) 65 | - `from_organization` (String) 66 | - `from_postcode` (String) 67 | - `from_state` (String) 68 | - `id` (String) 69 | - `pagecount` (Number) 70 | - `service` (String) 71 | - `simplex` (Boolean) 72 | - `to_address_1` (String) 73 | - `to_address_2` (String) 74 | - `to_city` (String) 75 | - `to_country` (String) 76 | - `to_formatted` (String) 77 | - `to_name` (String) 78 | - `to_organization` (String) 79 | - `to_postcode` (String) 80 | - `to_state` (String) 81 | 82 | 83 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "mailform Provider" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # mailform Provider 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | provider "mailform" { 17 | # example configuration here 18 | } 19 | ``` 20 | 21 | 22 | ## Schema 23 | 24 | ### Optional 25 | 26 | - `api_token` (String) 27 | -------------------------------------------------------------------------------- /docs/resources/order.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "mailform_order Resource - terraform-provider-mailform" 4 | subcategory: "" 5 | description: |- 6 | Mailform order 7 | --- 8 | 9 | # mailform_order (Resource) 10 | 11 | Mailform order 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `from_address_1` (String) The street number and name of the sender of this envelope or postcard. 21 | - `from_city` (String) The address city of the sender of this envelope or postcard. 22 | - `from_country` (String) The address country of the sender of this envelope or postcard. Example "US" 23 | - `from_name` (String) The name of the sender of this envelope or postcard. 24 | - `from_postcode` (String) The address postcode or zip code of the sender of this envelope or postcard. Example "00000" 25 | - `from_state` (String) The address state of the sender of this envelope or postcard. Example "WA" 26 | - `service` (String) What shipping service/speed to use. Must be one of: `FEDEX_OVERNIGHT`, `USPS_PRIORITY_EXPRESS`, `USPS_PRIORITY`, `USPS_CERTIFIED_PHYSICAL_RECEIPT`, `USPS_CERTIFIED_RECEIPT`, `USPS_CERTIFIED`, `USPS_FIRST_CLASS`, `USPS_STANDARD`, `USPS_POSTCARD` 27 | - `to_address_1` (String) The street number and name of the recipient of this envelope or postcard. 28 | - `to_city` (String) The address state of the recipient of this envelope or postcard. 29 | - `to_country` (String) The address country of the recipient of this envelope or postcard. Example "US" 30 | - `to_name` (String) The name of the recipient of this envelope or postcard. 31 | - `to_postcode` (String) The address postcode or zip code of the recipient of this envelope or postcard. Example "00000" 32 | - `to_state` (String) The address postcode or zip code of the recipient of this envelope or postcard. Example "WA" 33 | 34 | ### Optional 35 | 36 | - `amount` (Number) The amount of the check associated with this order, in cents. Required if a check is to be included in this order. 37 | - `bank_account` (String) The identifier of the bank account for the check associated with this order. Required if a check is to be included in this order. 38 | - `check_memo` (String) The memo line for the check associated with this order. 39 | - `check_name` (String) The name of the recipient of the check associated with this order. Required if a check is to be included in this order. 40 | - `check_number` (Number) The number of the check associated with this order. Required if a check is to be included in this order. 41 | - `color` (Boolean) True if the document should be printed in color, false if the document should be printed in black and white. 42 | - `company` (String) The company that this order should be associated with. 43 | - `customer_reference` (String) An optional customer reference to be attached to the order. 44 | - `flat` (Boolean) True if the document MUST be mailed in a flat envelope, false if it is acceptable to mail the document folded. 45 | - `from_address_2` (String) The suite or room number of the sender of this envelope or postcard. 46 | - `from_organization` (String) The organization or company associated with this address. 47 | - `message` (String) The message to be printed on the non-picture side of a postcard.. 48 | - `pdf_file` (String) File path of PDF to be printed and mailed by mailform. Orders cannot be updated/deleted. 49 | - `pdf_url` (String) URL of PDF to be printed and mailed by mailform. 50 | - `simplex` (Boolean) True if the document should be printed one page to a sheet, false if the document can be printed on both sides of a sheet. 51 | - `stamp` (Boolean) True if the document MUST use a real postage stamp, false if it is acceptable to mail the document using metered postage or an imprint. 52 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 53 | - `to_address_2` (String) The suite or room number of the recipient of this envelope or postcard. 54 | - `to_organization` (String) The organization or company associated with the recipient of this envelope or postcard. 55 | - `wait_until_fulfilled` (Boolean) Wait until order is fulfilled (mailed). Default timeout is 5 days, but may be overridden using a timeouts block. 56 | - `webhook` (String) The webhook that should receive notifications about order updates to this order. 57 | 58 | ### Read-Only 59 | 60 | - `account` (String) 61 | - `cancellation_reason` (String) 62 | - `cancelled` (String) 63 | - `channel` (String) 64 | - `created` (String) 65 | - `id` (String) The ID of this resource. 66 | - `lineitems` (List of Object) (see [below for nested schema](#nestedatt--lineitems)) 67 | - `modified` (String) 68 | - `object` (String) 69 | - `state` (String) 70 | - `test_mode` (Boolean) 71 | - `total` (Number) 72 | 73 | 74 | ### Nested Schema for `timeouts` 75 | 76 | Optional: 77 | 78 | - `create` (String) 79 | 80 | 81 | 82 | ### Nested Schema for `lineitems` 83 | 84 | Read-Only: 85 | 86 | - `color` (Boolean) 87 | - `from_address_1` (String) 88 | - `from_address_2` (String) 89 | - `from_city` (String) 90 | - `from_country` (String) 91 | - `from_formatted` (String) 92 | - `from_name` (String) 93 | - `from_organization` (String) 94 | - `from_postcode` (String) 95 | - `from_state` (String) 96 | - `id` (String) 97 | - `pagecount` (Number) 98 | - `service` (String) 99 | - `simplex` (Boolean) 100 | - `to_address_1` (String) 101 | - `to_address_2` (String) 102 | - `to_city` (String) 103 | - `to_country` (String) 104 | - `to_formatted` (String) 105 | - `to_name` (String) 106 | - `to_organization` (String) 107 | - `to_postcode` (String) 108 | - `to_state` (String) 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/resources/pdf.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "mailform_pdf Resource - terraform-provider-mailform" 4 | subcategory: "" 5 | description: |- 6 | Render a PDF and write to a local file. 7 | --- 8 | 9 | # mailform_pdf (Resource) 10 | 11 | Render a PDF and write to a local file. 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `filename` (String) The path to the PDF file that will be created 21 | 22 | ### Optional 23 | 24 | - `content` (String) Content of PDF 25 | - `header` (String) Header/title of PDF 26 | - `image_filename` (String) The image file to be converted to a PDF. Typically used for postcards 27 | 28 | ### Read-Only 29 | 30 | - `id` (String) The ID of this resource. 31 | 32 | 33 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This directory contains examples that are mostly used for documentation, but can also be run/tested manually via the Terraform CLI. 4 | 5 | The document generation tool looks for files in the following locations by default. All other *.tf files besides the ones mentioned below are ignored by the documentation tool. This is useful for creating examples that can run and/or ar testable even if some parts are not relevant for the documentation. 6 | 7 | * **provider/provider.tf** example file for the provider index page 8 | * **data-sources//data-source.tf** example file for the named data source page 9 | * **resources//resource.tf** example file for the named data source page 10 | -------------------------------------------------------------------------------- /examples/data-sources/mailform_order/data-source.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | mailform = { 4 | source = "circa10a/mailform" 5 | } 6 | } 7 | } 8 | 9 | data "mailform_order" "sample_order" { 10 | id = "foo" 11 | } 12 | 13 | output "order_info" { 14 | value = data.mailform_order.sample_order 15 | } 16 | -------------------------------------------------------------------------------- /examples/provider/provider.tf: -------------------------------------------------------------------------------- 1 | provider "mailform" { 2 | # example configuration here 3 | } 4 | -------------------------------------------------------------------------------- /examples/resources/mailform_order/order.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | mailform = { 4 | source = "circa10a/mailform" 5 | } 6 | } 7 | } 8 | 9 | resource "mailform_pdf" "example" { 10 | header = "My Resume" 11 | content = "Some resume contents" 12 | filename = "./test.pdf" 13 | } 14 | 15 | resource "mailform_order" "example" { 16 | pdf_file = mailform_pdf.example.filename 17 | service = "USPS_PRIORITY" 18 | to_name = "A name" 19 | to_address_1 = "Address 1" 20 | to_city = "Seattle" 21 | to_state = "WA" 22 | to_postcode = "00000" 23 | to_country = "US" 24 | from_name = "My name" 25 | from_address_1 = "My Address 1" 26 | from_city = "Dallas" 27 | from_state = "TX" 28 | from_postcode = "00000" 29 | from_country = "US" 30 | } 31 | -------------------------------------------------------------------------------- /examples/resources/mailform_pdf/pdf.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | mailform = { 4 | source = "circa10a/mailform" 5 | } 6 | } 7 | } 8 | 9 | resource "mailform_pdf" "example" { 10 | header = "My Resume" 11 | content = "Some resume contents" 12 | filename = "./test.pdf" 13 | } 14 | 15 | resource "mailform_pdf" "converted_image" { 16 | image_filename = "./myimage.jpg" 17 | filename = "./myimage.pdf" 18 | } 19 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/circa10a/terraform-provider-mailform 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/circa10a/go-mailform v0.6.0 7 | github.com/hashicorp/terraform-plugin-docs v0.13.0 8 | github.com/hashicorp/terraform-plugin-log v0.8.0 9 | github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0 10 | github.com/jung-kurt/gofpdf v1.16.2 11 | golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 12 | ) 13 | 14 | require ( 15 | github.com/Masterminds/goutils v1.1.1 // indirect 16 | github.com/Masterminds/semver/v3 v3.1.1 // indirect 17 | github.com/Masterminds/sprig/v3 v3.2.2 // indirect 18 | github.com/agext/levenshtein v1.2.3 // indirect 19 | github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect 20 | github.com/armon/go-radix v1.0.0 // indirect 21 | github.com/bgentry/speakeasy v0.1.0 // indirect 22 | github.com/fatih/color v1.14.1 // indirect 23 | github.com/go-resty/resty/v2 v2.7.0 // indirect 24 | github.com/golang/protobuf v1.5.2 // indirect 25 | github.com/google/go-cmp v0.5.9 // indirect 26 | github.com/google/uuid v1.3.0 // indirect 27 | github.com/hashicorp/errwrap v1.1.0 // indirect 28 | github.com/hashicorp/go-checkpoint v0.5.0 // indirect 29 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 30 | github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect 31 | github.com/hashicorp/go-hclog v1.4.0 // indirect 32 | github.com/hashicorp/go-multierror v1.1.1 // indirect 33 | github.com/hashicorp/go-plugin v1.4.8 // indirect 34 | github.com/hashicorp/go-uuid v1.0.3 // indirect 35 | github.com/hashicorp/go-version v1.6.0 // indirect 36 | github.com/hashicorp/hc-install v0.5.0 // indirect 37 | github.com/hashicorp/hcl/v2 v2.16.1 // indirect 38 | github.com/hashicorp/logutils v1.0.0 // indirect 39 | github.com/hashicorp/terraform-exec v0.17.3 // indirect 40 | github.com/hashicorp/terraform-json v0.15.0 // indirect 41 | github.com/hashicorp/terraform-plugin-go v0.14.3 // indirect 42 | github.com/hashicorp/terraform-registry-address v0.1.0 // indirect 43 | github.com/hashicorp/terraform-svchost v0.1.0 // indirect 44 | github.com/hashicorp/yamux v0.1.1 // indirect 45 | github.com/huandu/xstrings v1.3.2 // indirect 46 | github.com/imdario/mergo v0.3.13 // indirect 47 | github.com/mattn/go-colorable v0.1.13 // indirect 48 | github.com/mattn/go-isatty v0.0.17 // indirect 49 | github.com/mitchellh/cli v1.1.5 // indirect 50 | github.com/mitchellh/copystructure v1.2.0 // indirect 51 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect 52 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 53 | github.com/mitchellh/mapstructure v1.5.0 // indirect 54 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 55 | github.com/oklog/run v1.1.0 // indirect 56 | github.com/posener/complete v1.2.3 // indirect 57 | github.com/russross/blackfriday v1.6.0 // indirect 58 | github.com/shopspring/decimal v1.3.1 // indirect 59 | github.com/spf13/cast v1.5.0 // indirect 60 | github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect 61 | github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect 62 | github.com/vmihailenco/tagparser v0.1.2 // indirect 63 | github.com/zclconf/go-cty v1.13.0 // indirect 64 | golang.org/x/crypto v0.6.0 // indirect 65 | golang.org/x/mod v0.7.0 // indirect 66 | golang.org/x/net v0.7.0 // indirect 67 | golang.org/x/sys v0.5.0 // indirect 68 | golang.org/x/text v0.7.0 // indirect 69 | google.golang.org/appengine v1.6.7 // indirect 70 | google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514 // indirect 71 | google.golang.org/grpc v1.53.0 // indirect 72 | google.golang.org/protobuf v1.28.1 // indirect 73 | ) 74 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= 3 | github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= 4 | github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= 5 | github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= 6 | github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= 7 | github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= 8 | github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= 9 | github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= 10 | github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= 11 | github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= 12 | github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= 13 | github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= 14 | github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= 15 | github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= 16 | github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= 17 | github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= 18 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= 19 | github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= 20 | github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= 21 | github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= 22 | github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= 23 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 24 | github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= 25 | github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 26 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 27 | github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= 28 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 29 | github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= 30 | github.com/circa10a/go-mailform v0.6.0 h1:chAhILHtID+fdeOEfBRWJrVYwaSnVR+raocXumtMc0o= 31 | github.com/circa10a/go-mailform v0.6.0/go.mod h1:oCX+R+o4jbjRyFYlcfnDzjt+zALo1w7Gt1DG9Tz1qGg= 32 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 33 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 34 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 35 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 36 | github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= 37 | github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= 38 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 39 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 40 | github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= 41 | github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= 42 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= 43 | github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= 44 | github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= 45 | github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= 46 | github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= 47 | github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= 48 | github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= 49 | github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= 50 | github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= 51 | github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= 52 | github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= 53 | github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= 54 | github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 55 | github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= 56 | github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 57 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 58 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 59 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 60 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 61 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 62 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 63 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 64 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 65 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 66 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 67 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 68 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 69 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 70 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 71 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 72 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 73 | github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= 74 | github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 75 | github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= 76 | github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= 77 | github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 78 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 79 | github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= 80 | github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= 81 | github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= 82 | github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= 83 | github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= 84 | github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= 85 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 86 | github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= 87 | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= 88 | github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM= 89 | github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= 90 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 91 | github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= 92 | github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 93 | github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 94 | github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= 95 | github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 96 | github.com/hashicorp/hc-install v0.5.0 h1:D9bl4KayIYKEeJ4vUDe9L5huqxZXczKaykSRcmQ0xY0= 97 | github.com/hashicorp/hc-install v0.5.0/go.mod h1:JyzMfbzfSBSjoDCRPna1vi/24BEDxFaCPfdHtM5SCdo= 98 | github.com/hashicorp/hcl/v2 v2.16.1 h1:BwuxEMD/tsYgbhIW7UuI3crjovf3MzuFWiVgiv57iHg= 99 | github.com/hashicorp/hcl/v2 v2.16.1/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= 100 | github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= 101 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 102 | github.com/hashicorp/terraform-exec v0.17.3 h1:MX14Kvnka/oWGmIkyuyvL6POx25ZmKrjlaclkx3eErU= 103 | github.com/hashicorp/terraform-exec v0.17.3/go.mod h1:+NELG0EqQekJzhvikkeQsOAZpsw0cv/03rbeQJqscAI= 104 | github.com/hashicorp/terraform-json v0.15.0 h1:/gIyNtR6SFw6h5yzlbDbACyGvIhKtQi8mTsbkNd79lE= 105 | github.com/hashicorp/terraform-json v0.15.0/go.mod h1:+L1RNzjDU5leLFZkHTFTbJXaoqUC6TqXlFgDoOXrtvk= 106 | github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smPzZrt1Wlm9koLeKazY= 107 | github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ= 108 | github.com/hashicorp/terraform-plugin-go v0.14.3 h1:nlnJ1GXKdMwsC8g1Nh05tK2wsC3+3BL/DBBxFEki+j0= 109 | github.com/hashicorp/terraform-plugin-go v0.14.3/go.mod h1:7ees7DMZ263q8wQ6E4RdIdR6nHHJtrdt4ogX5lPkX1A= 110 | github.com/hashicorp/terraform-plugin-log v0.8.0 h1:pX2VQ/TGKu+UU1rCay0OlzosNKe4Nz1pepLXj95oyy0= 111 | github.com/hashicorp/terraform-plugin-log v0.8.0/go.mod h1:1myFrhVsBLeylQzYYEV17VVjtG8oYPRFdaZs7xdW2xs= 112 | github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0 h1:iNRjaJCatQS1rIbHs/vDvJ0GECsaGgxx780chA2Irpk= 113 | github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0/go.mod h1:XnVNLIS6bdMJbjSDujhX4Rlk24QpbGKbnrVFM4tZ7OU= 114 | github.com/hashicorp/terraform-registry-address v0.1.0 h1:W6JkV9wbum+m516rCl5/NjKxCyTVaaUBbzYcMzBDO3U= 115 | github.com/hashicorp/terraform-registry-address v0.1.0/go.mod h1:EnyO2jYO6j29DTHbJcm00E5nQTFeTtyZH3H5ycydQ5A= 116 | github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= 117 | github.com/hashicorp/terraform-svchost v0.1.0 h1:0+RcgZdZYNd81Vw7tu62g9JiLLvbOigp7QtyNh6CjXk= 118 | github.com/hashicorp/terraform-svchost v0.1.0/go.mod h1:ut8JaH0vumgdCfJaihdcZULqkAwHdQNwNH7taIDdsZM= 119 | github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= 120 | github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= 121 | github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 122 | github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= 123 | github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 124 | github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 125 | github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 126 | github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= 127 | github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= 128 | github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= 129 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 130 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 131 | github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= 132 | github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= 133 | github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 134 | github.com/jung-kurt/gofpdf v1.16.2 h1:jgbatWHfRlPYiK85qgevsZTHviWXKwB1TTiKdz5PtRc= 135 | github.com/jung-kurt/gofpdf v1.16.2/go.mod h1:1hl7y57EsiPAkLbOwzpzqgx1A30nQCk/YmFV8S2vmK0= 136 | github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= 137 | github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 138 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 139 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 140 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 141 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 142 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 143 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 144 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 145 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 146 | github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= 147 | github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= 148 | github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= 149 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 150 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 151 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 152 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 153 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 154 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 155 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 156 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 157 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 158 | github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= 159 | github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 160 | github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= 161 | github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= 162 | github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= 163 | github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= 164 | github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= 165 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 166 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 167 | github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= 168 | github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= 169 | github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= 170 | github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 171 | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= 172 | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 173 | github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 174 | github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= 175 | github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 176 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 177 | github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= 178 | github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= 179 | github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= 180 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 181 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 182 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 183 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 184 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 185 | github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= 186 | github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= 187 | github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= 188 | github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= 189 | github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= 190 | github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= 191 | github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= 192 | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 193 | github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= 194 | github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 195 | github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= 196 | github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 197 | github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= 198 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 199 | github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= 200 | github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= 201 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 202 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 203 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 204 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 205 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 206 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 207 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 208 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 209 | github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 210 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= 211 | github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= 212 | github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= 213 | github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= 214 | github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= 215 | github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= 216 | github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= 217 | github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= 218 | github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= 219 | github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= 220 | github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= 221 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 222 | github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= 223 | github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= 224 | github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= 225 | github.com/zclconf/go-cty v1.13.0 h1:It5dfKTTZHe9aeppbNOda3mN7Ag7sg6QkBNm6TkyFa0= 226 | github.com/zclconf/go-cty v1.13.0/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= 227 | github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= 228 | golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 229 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 230 | golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 231 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 232 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 233 | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 234 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 235 | golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= 236 | golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= 237 | golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= 238 | golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= 239 | golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 240 | golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 241 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 242 | golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= 243 | golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 244 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 245 | golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 246 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 247 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 248 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 249 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 250 | golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 251 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 252 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 253 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 254 | golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= 255 | golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 256 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 257 | golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 258 | golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= 259 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 260 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 261 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 262 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 263 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 264 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 265 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 266 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 267 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 268 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 269 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 270 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 271 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 272 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 273 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 274 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 275 | golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 276 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 277 | golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 278 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 279 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 280 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 281 | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 282 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 283 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 284 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 285 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 286 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 287 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 288 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 289 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 290 | golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= 291 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 292 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 293 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 294 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 295 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 296 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 297 | golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 298 | golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= 299 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 300 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 301 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 302 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 303 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 304 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 305 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 306 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 307 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 308 | google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= 309 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 310 | google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514 h1:rtNKfB++wz5mtDY2t5C8TXlU5y52ojSu7tZo0z7u8eQ= 311 | google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= 312 | google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= 313 | google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= 314 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 315 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 316 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= 317 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 318 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 319 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 320 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 321 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 322 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 323 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 324 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 325 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 326 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 327 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 328 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 329 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 330 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 331 | gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 332 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 333 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 334 | -------------------------------------------------------------------------------- /internal/provider/data_source_order.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | "time" 7 | 8 | "github.com/circa10a/go-mailform" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | ) 12 | 13 | var orderSchema = map[string]*schema.Schema{ 14 | "id": { 15 | Type: schema.TypeString, 16 | Required: true, 17 | }, 18 | "object": { 19 | Type: schema.TypeString, 20 | Computed: true, 21 | }, 22 | "created": { 23 | Type: schema.TypeString, 24 | Computed: true, 25 | }, 26 | "total": { 27 | Type: schema.TypeInt, 28 | Computed: true, 29 | }, 30 | "modified": { 31 | Type: schema.TypeString, 32 | Computed: true, 33 | }, 34 | "webhook": { 35 | Type: schema.TypeString, 36 | Computed: true, 37 | }, 38 | "lineitems": { 39 | Type: schema.TypeList, 40 | Computed: true, 41 | Elem: &schema.Resource{ 42 | Schema: map[string]*schema.Schema{ 43 | "id": { 44 | Type: schema.TypeString, 45 | Computed: true, 46 | }, 47 | "pagecount": { 48 | Type: schema.TypeInt, 49 | Computed: true, 50 | }, 51 | "to_name": { 52 | Type: schema.TypeString, 53 | Computed: true, 54 | }, 55 | "to_address_1": { 56 | Type: schema.TypeString, 57 | Computed: true, 58 | }, 59 | "to_address_2": { 60 | Type: schema.TypeString, 61 | Computed: true, 62 | }, 63 | "to_city": { 64 | Type: schema.TypeString, 65 | Computed: true, 66 | }, 67 | "to_state": { 68 | Type: schema.TypeString, 69 | Computed: true, 70 | }, 71 | "to_postcode": { 72 | Type: schema.TypeString, 73 | Computed: true, 74 | }, 75 | "to_country": { 76 | Type: schema.TypeString, 77 | Computed: true, 78 | }, 79 | "to_formatted": { 80 | Type: schema.TypeString, 81 | Computed: true, 82 | }, 83 | "to_organization": { 84 | Type: schema.TypeString, 85 | Computed: true, 86 | }, 87 | "from_name": { 88 | Type: schema.TypeString, 89 | Computed: true, 90 | }, 91 | "from_address_1": { 92 | Type: schema.TypeString, 93 | Computed: true, 94 | }, 95 | "from_address_2": { 96 | Type: schema.TypeString, 97 | Computed: true, 98 | }, 99 | "from_city": { 100 | Type: schema.TypeString, 101 | Computed: true, 102 | }, 103 | "from_state": { 104 | Type: schema.TypeString, 105 | Computed: true, 106 | }, 107 | "from_postcode": { 108 | Type: schema.TypeString, 109 | Computed: true, 110 | }, 111 | "from_country": { 112 | Type: schema.TypeString, 113 | Computed: true, 114 | }, 115 | "from_formatted": { 116 | Type: schema.TypeString, 117 | Computed: true, 118 | }, 119 | "from_organization": { 120 | Type: schema.TypeString, 121 | Computed: true, 122 | }, 123 | "simplex": { 124 | Type: schema.TypeBool, 125 | Computed: true, 126 | }, 127 | "color": { 128 | Type: schema.TypeBool, 129 | Computed: true, 130 | }, 131 | "service": { 132 | Type: schema.TypeString, 133 | Computed: true, 134 | }, 135 | }, 136 | }, 137 | }, 138 | "account": { 139 | Type: schema.TypeString, 140 | Computed: true, 141 | }, 142 | "customer_reference": { 143 | Type: schema.TypeString, 144 | Computed: true, 145 | }, 146 | "channel": { 147 | Type: schema.TypeString, 148 | Computed: true, 149 | }, 150 | "test_mode": { 151 | Type: schema.TypeBool, 152 | Computed: true, 153 | }, 154 | "state": { 155 | Type: schema.TypeString, 156 | Computed: true, 157 | }, 158 | "cancelled": { 159 | Type: schema.TypeString, 160 | Computed: true, 161 | }, 162 | "cancellation_reason": { 163 | Type: schema.TypeString, 164 | Computed: true, 165 | }, 166 | } 167 | 168 | func dataSourceOrder() *schema.Resource { 169 | return &schema.Resource{ 170 | // This description is used by the documentation generator and the language server. 171 | Description: "Order data source in the Terraform provider mailform.", 172 | ReadContext: orderRead, 173 | Schema: orderSchema, 174 | } 175 | } 176 | 177 | func orderRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { 178 | providerConfig := m.(map[string]interface{}) 179 | client := providerConfig["client"].(*mailform.Client) 180 | 181 | var diags diag.Diagnostics 182 | 183 | id := d.Get("id").(string) 184 | order, err := client.GetOrder(id) 185 | if err != nil { 186 | // handle the case where the order does not exist and we gracefully SetID("") I guess. 187 | // this allows the user to make decisions in tf code instead of having that shit just bail out. 188 | if strings.Contains(err.Error(), "order_not_found") { 189 | d.SetId("") 190 | return diags 191 | } 192 | return diag.FromErr(err) 193 | } 194 | 195 | d.SetId(order.Data.ID) 196 | 197 | if err := d.Set("object", order.Data.Object); err != nil { 198 | return diag.FromErr(err) 199 | } 200 | 201 | if err := d.Set("created", order.Data.Created.Format(time.RFC3339)); err != nil { 202 | return diag.FromErr(err) 203 | } 204 | 205 | if err := d.Set("total", order.Data.Total); err != nil { 206 | return diag.FromErr(err) 207 | } 208 | 209 | if err := d.Set("modified", order.Data.Modified.Format(time.RFC3339)); err != nil { 210 | return diag.FromErr(err) 211 | } 212 | 213 | if err := d.Set("webhook", order.Data.Webhook); err != nil { 214 | return diag.FromErr(err) 215 | } 216 | 217 | if err := d.Set("lineitems", flattenLineItems(order)); err != nil { 218 | return diag.FromErr(err) 219 | } 220 | 221 | if err := d.Set("account", order.Data.Account); err != nil { 222 | return diag.FromErr(err) 223 | } 224 | 225 | if err := d.Set("customer_reference", order.Data.CustomerReference); err != nil { 226 | return diag.FromErr(err) 227 | } 228 | 229 | if err := d.Set("channel", order.Data.Channel); err != nil { 230 | return diag.FromErr(err) 231 | } 232 | 233 | if err := d.Set("test_mode", order.Data.TestMode); err != nil { 234 | return diag.FromErr(err) 235 | } 236 | 237 | if err := d.Set("state", order.Data.State); err != nil { 238 | return diag.FromErr(err) 239 | } 240 | 241 | if err := d.Set("cancelled", order.Data.Cancelled.Format(time.RFC3339)); err != nil { 242 | return diag.FromErr(err) 243 | } 244 | 245 | if err := d.Set("cancellation_reason", order.Data.CancellationReason); err != nil { 246 | return diag.FromErr(err) 247 | } 248 | 249 | return diags 250 | } 251 | 252 | func flattenLineItems(order *mailform.Order) []any { 253 | if order != nil { 254 | lineItems := order.Data.Lineitems 255 | ois := make([]interface{}, len(lineItems), len(lineItems)) 256 | 257 | for i, orderItem := range lineItems { 258 | oi := make(map[string]interface{}) 259 | 260 | oi["id"] = orderItem.ID 261 | oi["pagecount"] = orderItem.Pagecount 262 | oi["simplex"] = orderItem.Simplex 263 | oi["color"] = orderItem.Color 264 | oi["service"] = orderItem.Service 265 | oi["to_name"] = orderItem.To.Name 266 | oi["to_address_1"] = orderItem.To.Address1 267 | oi["to_address_2"] = orderItem.To.Address2 268 | oi["to_city"] = orderItem.To.City 269 | oi["to_postcode"] = orderItem.To.Postcode 270 | oi["to_country"] = orderItem.To.Country 271 | oi["to_formatted"] = orderItem.To.Formatted 272 | oi["to_organization"] = orderItem.To.Organization 273 | oi["from_name"] = orderItem.From.Name 274 | oi["from_address_1"] = orderItem.From.Address1 275 | oi["from_address_2"] = orderItem.From.Address2 276 | oi["from_state"] = orderItem.From.State 277 | oi["from_postcode"] = orderItem.From.Postcode 278 | oi["from_country"] = orderItem.From.Country 279 | oi["from_formatted"] = orderItem.From.Formatted 280 | oi["from_organization"] = orderItem.From.Organization 281 | 282 | ois[i] = oi 283 | } 284 | 285 | return ois 286 | } 287 | 288 | return make([]interface{}, 0) 289 | } 290 | -------------------------------------------------------------------------------- /internal/provider/data_source_order_test.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "regexp" 5 | "testing" 6 | 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" 8 | ) 9 | 10 | func TestAccDataSourceOrder(t *testing.T) { 11 | t.Skip("data source not yet implemented, remove this once you add your own code") 12 | 13 | resource.UnitTest(t, resource.TestCase{ 14 | PreCheck: func() { testAccPreCheck(t) }, 15 | ProviderFactories: providerFactories, 16 | Steps: []resource.TestStep{ 17 | { 18 | Config: testAccDataSourceOrder, 19 | Check: resource.ComposeTestCheckFunc( 20 | resource.TestMatchResourceAttr( 21 | "data.mailform_order.foo", "sample_attribute", regexp.MustCompile("^ba")), 22 | ), 23 | }, 24 | }, 25 | }) 26 | } 27 | 28 | const testAccDataSourceOrder = ` 29 | data "mailform_order" "foo" { 30 | sample_attribute = "bar" 31 | } 32 | ` 33 | -------------------------------------------------------------------------------- /internal/provider/provider.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/circa10a/go-mailform" 7 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | const ( 12 | mailformTokenAPIEnvVar = "MAILFORM_API_TOKEN" 13 | ) 14 | 15 | func init() { 16 | // Set descriptions to support markdown syntax, this will be used in document generation 17 | // and the language server. 18 | schema.DescriptionKind = schema.StringMarkdown 19 | 20 | // Customize the content of descriptions when output. For example you can add defaults on 21 | // to the exported descriptions if present. 22 | // schema.SchemaDescriptionBuilder = func(s *schema.Schema) string { 23 | // desc := s.Description 24 | // if s.Default != nil { 25 | // desc += fmt.Sprintf(" Defaults to `%v`.", s.Default) 26 | // } 27 | // return strings.TrimSpace(desc) 28 | // } 29 | } 30 | 31 | func New(version string) func() *schema.Provider { 32 | return func() *schema.Provider { 33 | p := &schema.Provider{ 34 | Schema: map[string]*schema.Schema{ 35 | "api_token": { 36 | Type: schema.TypeString, 37 | Optional: true, 38 | DefaultFunc: schema.EnvDefaultFunc(mailformTokenAPIEnvVar, nil), 39 | }, 40 | }, 41 | DataSourcesMap: map[string]*schema.Resource{ 42 | "mailform_order": dataSourceOrder(), 43 | }, 44 | ResourcesMap: map[string]*schema.Resource{ 45 | "mailform_order": resourceMailformOrder(), 46 | "mailform_pdf": resourcePDF(), 47 | }, 48 | ConfigureContextFunc: providerConfigure, 49 | } 50 | 51 | return p 52 | } 53 | } 54 | 55 | func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { 56 | var diags diag.Diagnostics 57 | 58 | api_token := d.Get("api_token").(string) 59 | client, err := mailform.New(&mailform.Config{ 60 | Token: api_token, 61 | }) 62 | if err != nil { 63 | return nil, diag.FromErr(err) 64 | } 65 | providerConfig := make(map[string]interface{}) 66 | providerConfig["client"] = client 67 | return providerConfig, diags 68 | } 69 | -------------------------------------------------------------------------------- /internal/provider/provider_test.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 7 | ) 8 | 9 | // providerFactories are used to instantiate a provider during acceptance testing. 10 | // The factory function will be invoked for every Terraform CLI command executed 11 | // to create a provider server to which the CLI can reattach. 12 | var providerFactories = map[string]func() (*schema.Provider, error){ 13 | "mailform": func() (*schema.Provider, error) { 14 | return New("dev")(), nil 15 | }, 16 | } 17 | 18 | func TestProvider(t *testing.T) { 19 | if err := New("dev")().InternalValidate(); err != nil { 20 | t.Fatalf("err: %s", err) 21 | } 22 | } 23 | 24 | func testAccPreCheck(t *testing.T) { 25 | // You can add code here to run prior to any test case execution, for example assertions 26 | // about the appropriate environment variables being set are common to see in a pre-check 27 | // function. 28 | } 29 | -------------------------------------------------------------------------------- /internal/provider/resource_order.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "strings" 8 | "time" 9 | 10 | "github.com/circa10a/go-mailform" 11 | "github.com/hashicorp/terraform-plugin-log/tflog" 12 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 13 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 14 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 15 | "golang.org/x/exp/maps" 16 | ) 17 | 18 | const ( 19 | orderStatusPollInterval = time.Minute * 30 20 | orderFulFillmentDefaultTimeout = time.Hour * 24 * 5 // 5 days 21 | ) 22 | 23 | var ( 24 | errOrderCancelled = errors.New("order has been cancelled") 25 | ) 26 | 27 | var orderInputSchema = map[string]*schema.Schema{ 28 | "pdf_file": { 29 | Description: "File path of PDF to be printed and mailed by mailform. Orders cannot be updated/deleted.", 30 | Type: schema.TypeString, 31 | Optional: true, 32 | ConflictsWith: []string{"pdf_url"}, 33 | ForceNew: true, 34 | }, 35 | "pdf_url": { 36 | Description: "URL of PDF to be printed and mailed by mailform.", 37 | Type: schema.TypeString, 38 | Optional: true, 39 | ConflictsWith: []string{"pdf_file"}, 40 | ForceNew: true, 41 | }, 42 | "customer_reference": { 43 | Description: "An optional customer reference to be attached to the order.", 44 | Type: schema.TypeString, 45 | Optional: true, 46 | ForceNew: true, 47 | }, 48 | "service": { 49 | Description: fmt.Sprintf("What shipping service/speed to use. Must be one of: `%s`", strings.Join(mailform.ServiceCodes, "`, `")), 50 | Type: schema.TypeString, 51 | Required: true, 52 | ValidateFunc: validation.StringInSlice(mailform.ServiceCodes, false), 53 | ForceNew: true, 54 | }, 55 | "webhook": { 56 | Description: "The webhook that should receive notifications about order updates to this order.", 57 | Type: schema.TypeString, 58 | Optional: true, 59 | ValidateFunc: validation.IsURLWithHTTPorHTTPS, 60 | ForceNew: true, 61 | }, 62 | "company": { 63 | Description: "The company that this order should be associated with.", 64 | Type: schema.TypeString, 65 | Optional: true, 66 | ForceNew: true, 67 | }, 68 | "simplex": { 69 | Description: "True if the document should be printed one page to a sheet, false if the document can be printed on both sides of a sheet.", 70 | Type: schema.TypeBool, 71 | Optional: true, 72 | ForceNew: true, 73 | }, 74 | "color": { 75 | Description: "True if the document should be printed in color, false if the document should be printed in black and white.", 76 | Type: schema.TypeBool, 77 | Optional: true, 78 | ForceNew: true, 79 | }, 80 | "flat": { 81 | Description: "True if the document MUST be mailed in a flat envelope, false if it is acceptable to mail the document folded.", 82 | Type: schema.TypeBool, 83 | Optional: true, 84 | ForceNew: true, 85 | }, 86 | "stamp": { 87 | Description: "True if the document MUST use a real postage stamp, false if it is acceptable to mail the document using metered postage or an imprint.", 88 | Type: schema.TypeBool, 89 | Optional: true, 90 | ForceNew: true, 91 | }, 92 | "message": { 93 | Description: "The message to be printed on the non-picture side of a postcard..", 94 | Type: schema.TypeString, 95 | Optional: true, 96 | ForceNew: true, 97 | }, 98 | "to_name": { 99 | Description: "The name of the recipient of this envelope or postcard.", 100 | Type: schema.TypeString, 101 | Required: true, 102 | ForceNew: true, 103 | }, 104 | "to_organization": { 105 | Description: "The organization or company associated with the recipient of this envelope or postcard.", 106 | Type: schema.TypeString, 107 | Optional: true, 108 | ForceNew: true, 109 | }, 110 | "to_address_1": { 111 | Description: "The street number and name of the recipient of this envelope or postcard.", 112 | Type: schema.TypeString, 113 | Required: true, 114 | ForceNew: true, 115 | }, 116 | "to_address_2": { 117 | Description: "The suite or room number of the recipient of this envelope or postcard.", 118 | Type: schema.TypeString, 119 | Optional: true, 120 | ForceNew: true, 121 | }, 122 | "to_city": { 123 | Description: "The address state of the recipient of this envelope or postcard.", 124 | Type: schema.TypeString, 125 | Required: true, 126 | ForceNew: true, 127 | }, 128 | "to_state": { 129 | Description: "The address postcode or zip code of the recipient of this envelope or postcard. Example \"WA\"", 130 | Type: schema.TypeString, 131 | Required: true, 132 | ForceNew: true, 133 | }, 134 | "to_postcode": { 135 | Description: "The address postcode or zip code of the recipient of this envelope or postcard. Example \"00000\"", 136 | Type: schema.TypeString, 137 | Required: true, 138 | ForceNew: true, 139 | }, 140 | "to_country": { 141 | Description: "The address country of the recipient of this envelope or postcard. Example \"US\"", 142 | Type: schema.TypeString, 143 | Required: true, 144 | ForceNew: true, 145 | }, 146 | "from_name": { 147 | Description: "The name of the sender of this envelope or postcard.", 148 | Type: schema.TypeString, 149 | Required: true, 150 | ForceNew: true, 151 | }, 152 | "from_organization": { 153 | Description: "The organization or company associated with this address.", 154 | Type: schema.TypeString, 155 | Optional: true, 156 | ForceNew: true, 157 | }, 158 | "from_address_1": { 159 | Description: "The street number and name of the sender of this envelope or postcard.", 160 | Type: schema.TypeString, 161 | Required: true, 162 | ForceNew: true, 163 | }, 164 | "from_address_2": { 165 | Description: "The suite or room number of the sender of this envelope or postcard.", 166 | Type: schema.TypeString, 167 | Optional: true, 168 | ForceNew: true, 169 | }, 170 | "from_city": { 171 | Description: "The address city of the sender of this envelope or postcard.", 172 | Type: schema.TypeString, 173 | Required: true, 174 | ForceNew: true, 175 | }, 176 | "from_state": { 177 | Description: "The address state of the sender of this envelope or postcard. Example \"WA\"", 178 | Type: schema.TypeString, 179 | Required: true, 180 | ForceNew: true, 181 | }, 182 | "from_postcode": { 183 | Description: "The address postcode or zip code of the sender of this envelope or postcard. Example \"00000\"", 184 | Type: schema.TypeString, 185 | Required: true, 186 | ForceNew: true, 187 | }, 188 | "from_country": { 189 | Description: "The address country of the sender of this envelope or postcard. Example \"US\"", 190 | Type: schema.TypeString, 191 | Required: true, 192 | ForceNew: true, 193 | }, 194 | "bank_account": { 195 | Description: "The identifier of the bank account for the check associated with this order. Required if a check is to be included in this order.", 196 | Type: schema.TypeString, 197 | Optional: true, 198 | ForceNew: true, 199 | }, 200 | "amount": { 201 | Description: "The amount of the check associated with this order, in cents. Required if a check is to be included in this order.", 202 | Type: schema.TypeInt, 203 | Optional: true, 204 | ForceNew: true, 205 | }, 206 | "check_name": { 207 | Description: "The name of the recipient of the check associated with this order. Required if a check is to be included in this order.", 208 | Type: schema.TypeString, 209 | Optional: true, 210 | ForceNew: true, 211 | }, 212 | "check_number": { 213 | Description: "The number of the check associated with this order. Required if a check is to be included in this order.", 214 | Type: schema.TypeInt, 215 | Optional: true, 216 | ForceNew: true, 217 | }, 218 | "check_memo": { 219 | Description: "The memo line for the check associated with this order.", 220 | Type: schema.TypeString, 221 | Optional: true, 222 | ForceNew: true, 223 | }, 224 | "wait_until_fulfilled": { 225 | Description: "Wait until order is fulfilled (mailed). Default timeout is 5 days, but may be overridden using a timeouts block.", 226 | Type: schema.TypeBool, 227 | Optional: true, 228 | ForceNew: true, 229 | }, 230 | // Computed 231 | "id": { 232 | Type: schema.TypeString, 233 | Computed: true, 234 | }, 235 | } 236 | 237 | // getOrderCreateSchema merges the input fields for the mailform_order resource and computed fields for a mailform_order data source 238 | func getOrderCreateSchema() map[string]*schema.Schema { 239 | merged := map[string]*schema.Schema{} 240 | maps.Copy(merged, orderSchema) 241 | // We copy input last so that webhook is set as input and not computed 242 | maps.Copy(merged, orderInputSchema) 243 | return merged 244 | } 245 | 246 | func resourceMailformOrder() *schema.Resource { 247 | return &schema.Resource{ 248 | Description: "Mailform order", 249 | CreateContext: resourceMailformOrderCreate, 250 | ReadContext: orderRead, 251 | DeleteContext: resourceMailformOrderDelete, 252 | Schema: getOrderCreateSchema(), 253 | Timeouts: &schema.ResourceTimeout{ 254 | Create: schema.DefaultTimeout(orderFulFillmentDefaultTimeout), 255 | }, 256 | } 257 | } 258 | 259 | func resourceMailformOrderCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { 260 | providerConfig := m.(map[string]interface{}) 261 | client := providerConfig["client"].(*mailform.Client) 262 | order := mailform.OrderInput{ 263 | FilePath: d.Get("pdf_file").(string), 264 | URL: d.Get("pdf_url").(string), 265 | CustomerReference: d.Get("customer_reference").(string), 266 | Service: d.Get("service").(string), 267 | Webhook: d.Get("webhook").(string), 268 | Company: d.Get("company").(string), 269 | Simplex: d.Get("simplex").(bool), 270 | Color: d.Get("color").(bool), 271 | Flat: d.Get("flat").(bool), 272 | Stamp: d.Get("stamp").(bool), 273 | Message: d.Get("message").(string), 274 | ToName: d.Get("to_name").(string), 275 | ToOrganization: d.Get("to_organization").(string), 276 | ToAddress1: d.Get("to_address_1").(string), 277 | ToAddress2: d.Get("to_address_2").(string), 278 | ToCity: d.Get("to_city").(string), 279 | ToState: d.Get("to_state").(string), 280 | ToPostcode: d.Get("to_postcode").(string), 281 | ToCountry: d.Get("to_country").(string), 282 | FromName: d.Get("from_name").(string), 283 | FromOrganization: d.Get("from_organization").(string), 284 | FromAddress1: d.Get("from_address_1").(string), 285 | FromAddress2: d.Get("from_address_2").(string), 286 | FromCity: d.Get("from_city").(string), 287 | FromState: d.Get("from_state").(string), 288 | FromPostcode: d.Get("from_postcode").(string), 289 | FromCountry: d.Get("from_country").(string), 290 | BankAccount: d.Get("bank_account").(string), 291 | Amount: d.Get("amount").(int), 292 | CheckName: d.Get("check_name").(string), 293 | CheckNumber: d.Get("check_number").(int), 294 | CheckMemo: d.Get("check_memo").(string), 295 | } 296 | 297 | result, err := client.CreateOrder(order) 298 | if err != nil { 299 | return diag.FromErr(err) 300 | } 301 | 302 | orderID := result.Data.ID 303 | d.SetId(orderID) 304 | 305 | if d.Get("wait_until_fulfilled").(bool) { 306 | ticker := time.NewTicker(orderStatusPollInterval) 307 | timer := time.NewTimer(d.Timeout(schema.TimeoutCreate)) 308 | 309 | // If order was cancelled, break early 310 | order, err := client.GetOrder(orderID) 311 | if err != nil { 312 | tflog.Error(ctx, err.Error()) 313 | } 314 | orderStatus := order.Data.State 315 | if orderStatus == mailform.StatusCancelled { 316 | return diag.FromErr(errOrderCancelled) 317 | } 318 | 319 | for { 320 | select { 321 | case <-ticker.C: 322 | // Get order status 323 | order, err := client.GetOrder(orderID) 324 | if err != nil { 325 | tflog.Error(ctx, err.Error()) 326 | } 327 | orderStatus := order.Data.State 328 | tflog.Debug(ctx, fmt.Sprintf("order state: %s", orderStatus)) 329 | 330 | // If order was cancelled, break 331 | if orderStatus == mailform.StatusCancelled { 332 | return diag.FromErr(errOrderCancelled) 333 | } 334 | 335 | // If order has been mailed 336 | if orderStatus == mailform.StatusFulfilled { 337 | break 338 | } 339 | select { 340 | case <-timer.C: 341 | return diag.FromErr(errors.New("waiting for order to be fulfilled timed out")) 342 | default: 343 | break 344 | } 345 | case <-ctx.Done(): 346 | return diag.FromErr(errors.New("waiting for order cancelled")) 347 | } 348 | } 349 | 350 | } 351 | 352 | // Set computed fields in state. Saves alot of copy paste by just running an extra GET after creating the order 353 | return orderRead(ctx, d, m) 354 | } 355 | 356 | func resourceMailformOrderDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { 357 | // API doesn't support deleting orders, we simply just remove from state 358 | d.SetId("") 359 | return nil 360 | } 361 | -------------------------------------------------------------------------------- /internal/provider/resource_pdf.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "context" 5 | "crypto/sha1" 6 | "encoding/hex" 7 | "errors" 8 | "io/ioutil" 9 | "net/http" 10 | "os" 11 | 12 | "github.com/hashicorp/terraform-plugin-log/tflog" 13 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 14 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 15 | "github.com/jung-kurt/gofpdf" 16 | ) 17 | 18 | func resourcePDF() *schema.Resource { 19 | return &schema.Resource{ 20 | // This description is used by the documentation generator and the language server. 21 | Description: "Render a PDF and write to a local file.", 22 | 23 | CreateContext: resourcePDFCreate, 24 | ReadContext: resourcePDFRead, 25 | DeleteContext: resourcePDFDelete, 26 | 27 | Schema: map[string]*schema.Schema{ 28 | "filename": { 29 | Description: "The path to the PDF file that will be created", 30 | Type: schema.TypeString, 31 | Required: true, 32 | ForceNew: true, 33 | }, 34 | "header": { 35 | Description: "Header/title of PDF", 36 | Type: schema.TypeString, 37 | Optional: true, 38 | ForceNew: true, 39 | ConflictsWith: []string{ 40 | "image_filename", 41 | }, 42 | }, 43 | "content": { 44 | Description: "Content of PDF", 45 | Type: schema.TypeString, 46 | Optional: true, 47 | ForceNew: true, 48 | ConflictsWith: []string{ 49 | "image_filename", 50 | }, 51 | }, 52 | "image_filename": { 53 | Description: "The image file to be converted to a PDF. Typically used for postcards", 54 | Type: schema.TypeString, 55 | Optional: true, 56 | ForceNew: true, 57 | ConflictsWith: []string{ 58 | "header", 59 | "content", 60 | }, 61 | ValidateFunc: func(val any, key string) (warns []string, errs []error) { 62 | buf := make([]byte, 512) 63 | 64 | imageFilename := val.(string) 65 | file, err := os.Open(imageFilename) 66 | if err != nil { 67 | errs = append(errs, err) 68 | return warns, errs 69 | } 70 | 71 | defer file.Close() 72 | 73 | _, err = file.Read(buf) 74 | if err != nil { 75 | errs = append(errs, err) 76 | return warns, errs 77 | } 78 | 79 | contentType := http.DetectContentType(buf) 80 | 81 | if contentType != "image/png" && contentType != "image/jpeg" { 82 | errs = append(errs, errors.New("image file is not a valid image")) 83 | return warns, errs 84 | } 85 | 86 | return warns, errs 87 | }, 88 | }, 89 | }, 90 | } 91 | } 92 | 93 | func resourcePDFCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { 94 | 95 | // Used for generating pdfs and also converting pdf's to images 96 | filename := d.Get("filename").(string) 97 | 98 | // If an image, convert to pdf 99 | if imageFilename, ok := d.GetOk("image_filename"); ok { 100 | err := convertImage(imageFilename.(string), filename) 101 | if err != nil { 102 | defer resourcePDFDelete(ctx, d, filename) 103 | return diag.FromErr(err) 104 | } 105 | } else { 106 | // Generate content if not image 107 | header := d.Get("header").(string) 108 | content := d.Get("content").(string) 109 | 110 | err := renderPDF(header, content, filename) 111 | if err != nil { 112 | return diag.FromErr(err) 113 | } 114 | } 115 | 116 | outputContent, err := ioutil.ReadFile(filename) 117 | if err != nil { 118 | return diag.FromErr(err) 119 | } 120 | 121 | checksum := sha1.Sum([]byte(outputContent)) 122 | d.SetId(hex.EncodeToString(checksum[:])) 123 | 124 | tflog.Trace(ctx, "created a pdf resource") 125 | 126 | return nil 127 | } 128 | 129 | func resourcePDFRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { 130 | // If the output file doesn't exist, mark the resource for creation. 131 | outputPath := d.Get("filename").(string) 132 | if _, err := os.Stat(outputPath); os.IsNotExist(err) { 133 | d.SetId("") 134 | return nil 135 | } 136 | 137 | // Verify that the content of the destination file matches the content we 138 | // expect. Otherwise, the file might have been modified externally, and we 139 | // must reconcile. 140 | outputContent, err := ioutil.ReadFile(outputPath) 141 | if err != nil { 142 | return diag.FromErr(err) 143 | } 144 | 145 | outputChecksum := sha1.Sum(outputContent) 146 | if hex.EncodeToString(outputChecksum[:]) != d.Id() { 147 | d.SetId("") 148 | return nil 149 | } 150 | 151 | return nil 152 | } 153 | 154 | func resourcePDFDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { 155 | err := os.Remove(d.Get("filename").(string)) 156 | if err != nil { 157 | return diag.FromErr(err) 158 | } 159 | return nil 160 | } 161 | 162 | // renderPDF converts header + content to a pdf and writes to an output file 163 | func renderPDF(header string, content string, outputFilePath string) error { 164 | pdf := gofpdf.New(gofpdf.OrientationPortrait, "mm", gofpdf.PageSizeLetter, "") 165 | pdf.AddPage() 166 | pdf.SetTitle(header, false) 167 | pdf.SetFont("Arial", "B", 16) 168 | // Calculate width of title and position 169 | wd := pdf.GetStringWidth(header) + 6 170 | pdf.SetX((210 - wd) / 2) 171 | // Title 172 | pdf.CellFormat(wd, 9, header, "", 1, "C", false, 0, "") 173 | // Line break 174 | pdf.Ln(10) 175 | pdf.SetFont("Arial", "", 11) 176 | pdf.SetAutoPageBreak(true, 2.00) 177 | // Write ze content 178 | pdf.Write(8, content) 179 | 180 | return pdf.OutputFileAndClose(outputFilePath) 181 | } 182 | 183 | // convertImage converts input image path to pdf file 184 | func convertImage(inputFilePath, outputFilePath string) error { 185 | pdf := gofpdf.New(gofpdf.OrientationPortrait, "mm", gofpdf.PageSizeLetter, "") 186 | pdf.AddPage() 187 | pdf.Image(inputFilePath, 0, 0, 220, 280, false, "", 0, "") 188 | 189 | err := pdf.OutputFileAndClose(outputFilePath) 190 | if err != nil { 191 | return err 192 | } 193 | 194 | return nil 195 | } 196 | -------------------------------------------------------------------------------- /internal/provider/resource_pdf_test.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "regexp" 7 | "testing" 8 | 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" 11 | ) 12 | 13 | func TestAccResourcePDF(t *testing.T) { 14 | resource.UnitTest(t, resource.TestCase{ 15 | PreCheck: func() { testAccPreCheck(t) }, 16 | ProviderFactories: providerFactories, 17 | Steps: []resource.TestStep{ 18 | { 19 | Config: testAccResourcePDF, 20 | Check: resource.ComposeTestCheckFunc( 21 | resource.TestMatchResourceAttr( 22 | "mailform_pdf.example", "header", regexp.MustCompile("My Resume"), 23 | ), 24 | 25 | resource.TestMatchResourceAttr( 26 | "mailform_pdf.example", "content", regexp.MustCompile("Some resume contents"), 27 | ), 28 | resource.TestMatchResourceAttr( 29 | "mailform_pdf.example", "filename", regexp.MustCompile("./test.pdf"), 30 | ), 31 | ), 32 | }, 33 | }, 34 | CheckDestroy: checkFileDeleted("./test.pdf"), 35 | }) 36 | } 37 | 38 | const testAccResourcePDF = ` 39 | resource "mailform_pdf" "example" { 40 | header = "My Resume" 41 | content = "Some resume contents" 42 | filename = "./test.pdf" 43 | } 44 | ` 45 | 46 | func checkFileDeleted(shouldNotExistFile string) resource.TestCheckFunc { 47 | return func(*terraform.State) error { 48 | if _, err := os.Stat(shouldNotExistFile); os.IsNotExist(err) { 49 | return nil 50 | } 51 | return fmt.Errorf("file %s was not deleted", shouldNotExistFile) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | 6 | "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" 7 | "github.com/circa10a/terraform-provider-mailform/internal/provider" 8 | ) 9 | 10 | // Run "go generate" to format example terraform files and generate the docs for the registry/website 11 | 12 | // If you do not have terraform installed, you can remove the formatting command, but its suggested to 13 | // ensure the documentation is formatted properly. 14 | //go:generate terraform fmt -recursive ./examples/ 15 | 16 | // Run the docs generation tool, check its repository for more information on how it works and how docs 17 | // can be customized. 18 | //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs 19 | 20 | var ( 21 | // these will be set by the goreleaser configuration 22 | // to appropriate values for the compiled binary 23 | version string = "dev" 24 | 25 | // goreleaser can also pass the specific commit if you want 26 | // commit string = "" 27 | ) 28 | 29 | func main() { 30 | var debugMode bool 31 | 32 | flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve") 33 | flag.Parse() 34 | 35 | opts := &plugin.ServeOpts{ 36 | Debug: debugMode, 37 | 38 | ProviderAddr: "registry.terraform.io/circa10a/terraform-provider-mailform", 39 | 40 | ProviderFunc: provider.New(version), 41 | } 42 | 43 | plugin.Serve(opts) 44 | } 45 | -------------------------------------------------------------------------------- /terraform-registry-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "metadata": { 4 | "protocol_versions": ["5.0"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | package tools 5 | 6 | import ( 7 | // document generation 8 | _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" 9 | ) 10 | --------------------------------------------------------------------------------