├── .dockerignore ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── __modules └── todo-test-data │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── bin ├── build.sh ├── package-release.sh ├── tests_manual.sh └── tf_complete_build.sh ├── client ├── todo_list_client.go └── todos │ ├── add_one_parameters.go │ ├── add_one_responses.go │ ├── destroy_one_parameters.go │ ├── destroy_one_responses.go │ ├── find_todo_parameters.go │ ├── find_todo_responses.go │ ├── find_todos_parameters.go │ ├── find_todos_responses.go │ ├── todos_client.go │ ├── update_one_parameters.go │ └── update_one_responses.go ├── cmd └── todo-list-server │ └── main.go ├── docker-compose.yaml ├── docs └── tutorial.md ├── go.mod ├── go.sum ├── models ├── error.go ├── find_todos_okbody.go └── item.go ├── restapi ├── configure_todo_list.go ├── doc.go ├── embedded_spec.go ├── operations │ ├── todo_list_api.go │ └── todos │ │ ├── add_one.go │ │ ├── add_one_parameters.go │ │ ├── add_one_responses.go │ │ ├── add_one_urlbuilder.go │ │ ├── destroy_one.go │ │ ├── destroy_one_parameters.go │ │ ├── destroy_one_responses.go │ │ ├── destroy_one_urlbuilder.go │ │ ├── find_todo.go │ │ ├── find_todo_parameters.go │ │ ├── find_todo_responses.go │ │ ├── find_todo_urlbuilder.go │ │ ├── find_todos.go │ │ ├── find_todos_parameters.go │ │ ├── find_todos_responses.go │ │ ├── find_todos_urlbuilder.go │ │ ├── update_one.go │ │ ├── update_one_parameters.go │ │ ├── update_one_responses.go │ │ └── update_one_urlbuilder.go └── server.go ├── swagger.yaml ├── terraform-infrastructure-aws ├── README.md ├── backend.tf ├── bin │ ├── ip_vars.sh │ └── local-ip.sh ├── data.tf ├── files │ ├── daemon.json │ ├── startup_options.conf │ └── todo-list.service ├── frontend.tf ├── graph.png ├── graph.svg ├── key-pairs.tf ├── main.tf ├── outputs.tf ├── security-groups.tf └── variables.tf ├── terraform-infrastructure-tfcloud ├── README.md ├── data.tf ├── main.tf └── variables.tf ├── terraform-local-test ├── README.md ├── bin │ └── local-ip.sh ├── main.tf └── outputs.tf ├── terraform-tests-1 ├── main.tf ├── outputs.tf └── variables.tf ├── terraform-tests-2 ├── main.tf ├── outputs.tf └── variables.tf └── terraform-tests-3 ├── main.tf ├── outputs.tf └── variables.tf /.dockerignore: -------------------------------------------------------------------------------- 1 | # git 2 | .git 3 | 4 | # Terrform 5 | terraform.tfstate* 6 | .terraform 7 | *.log 8 | terraform-provider-todo/bin/ 9 | terraform-provider-todo/pkg/ 10 | 11 | # Binaries 12 | terraform-provider-todo 13 | terraform-provider-todo_v* 14 | todo-list-server 15 | main 16 | 17 | # System Files 18 | .DS_Store 19 | 20 | # Don't ignore these 21 | !/terraform-provider-todo/ 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Terrform 2 | tf-code/ 3 | plan.out 4 | terraform.tfstate* 5 | .terraform 6 | .terraform.lock.hcl 7 | *.log 8 | terraform-provider-todo/bin/ 9 | terraform-provider-todo/pkg/ 10 | cmd/todo-list-server/pkg/ 11 | cmd/todo-list-server/bin/ 12 | class-terraform-getstarted.md 13 | 14 | # Binaries 15 | terraform-provider-todo 16 | terraform-provider-todo_v* 17 | todo-list-server 18 | 19 | # System Files 20 | .DS_Store 21 | 22 | # Don't ignore these 23 | !/terraform-provider-todo/ 24 | !/cmd/todo-list-server/ 25 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.19-alpine AS build 2 | 3 | RUN apk --no-cache add \ 4 | bash \ 5 | gcc \ 6 | musl-dev \ 7 | openssl 8 | RUN mkdir -p /go/src/github.com/spkane/todo-for-terraform 9 | WORKDIR /go/src/github.com/spkane/todo-for-terraform 10 | # This copies in more than we need, but since we are 11 | # creating a second image it is not really a big deal. 12 | ADD . /go/src/github.com/spkane/todo-for-terraform 13 | RUN go build --ldflags '-linkmode external -extldflags "-static"' ./cmd/todo-list-server 14 | 15 | FROM alpine:3.14 AS deploy 16 | 17 | WORKDIR / 18 | 19 | RUN apk --no-cache add curl 20 | COPY --from=build /go/src/github.com/spkane/todo-for-terraform/todo-list-server / 21 | 22 | HEALTHCHECK --interval=15s --timeout=3s \ 23 | CMD curl -f http://127.0.0.1/?limit=1 || exit 1 24 | 25 | ENTRYPOINT ["/todo-list-server"] 26 | CMD ["--scheme=http", "--host=0.0.0.0", "--port=80"] 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Todo for Terraform 2 | 3 | * Requires (recent versions, but approximate): 4 | * terraform 0.13.X+ 5 | * go 1.15.X+ (compiling) 6 | * docker 20.10.X+ (build & test scripts) 7 | 8 | ## Todo Server 9 | 10 | ### Quick Start 11 | 12 | ```shell 13 | docker run --name todo-list -p 8080:80 spkane/todo-list-server:latest 14 | ``` 15 | 16 | ### Build 17 | 18 | ```shell 19 | ./bin/build.sh 20 | ``` 21 | 22 | ### Usage 23 | 24 | ```shell 25 | curl -i http://127.0.0.1:8080/ 26 | curl -i http://127.0.0.1:8080/ -d "{\"description\":\"message $RANDOM\",\"completed\":false}" -H 'Content-Type: application/spkane.todo-list.v1+json' 27 | curl -i http://127.0.0.1:8080/ -d "{\"description\":\"message $RANDOM\",\"completed\":false}" -H 'Content-Type: application/spkane.todo-list.v1+json' 28 | curl -i http://127.0.0.1:8080/ -d "{\"description\":\"message $RANDOM\",\"completed\":false}" -H 'Content-Type: application/spkane.todo-list.v1+json' 29 | curl -i http://127.0.0.1:8080/3 -X PUT -H 'Content-Type: application/spkane.todo-list.v1+json' -d '{"description":"go shopping",\"completed\":true}' 30 | curl -i http://127.0.0.1:8080/1 -X DELETE -H 'Content-Type: application/spkane.todo-list.v1+json' 31 | curl -i http://127.0.0.1:8080/3 -X DELETE -H 'Content-Type: application/spkane.todo-list.v1+json' 32 | curl -i http://127.0.0.1:8080 33 | ``` 34 | 35 | ## Build & Test 36 | 37 | ```shell 38 | ./bin/build.sh 39 | ``` 40 | 41 | The build script runs the Integration tests. If you want to run real local terraform tests, you can run this script: 42 | 43 | ```shell 44 | ./bin/tests_manual.sh 45 | ``` 46 | 47 | ## Terraform Provider 48 | 49 | The source code for the Terraform provider can be found here: 50 | 51 | - [spkane/terraform-provider-todo](https://github.com/spkane/terraform-provider-todo) 52 | 53 | In your terraform HCL you will need to reference the provider with something like this: 54 | 55 | ```hcl 56 | terraform { 57 | required_providers { 58 | todo = { 59 | source = "spkane/todo" 60 | version = "2.0.6" 61 | } 62 | } 63 | } 64 | ``` 65 | 66 | --- 67 | 68 | * *NOTE*: The todo server code for this project was directly forked from: 69 | * [github.com/go-swagger](https://github.com/go-swagger/go-swagger/tree/master/examples/tutorials/todo-list/server-complete) 70 | 71 | ## TODOs 72 | 73 | * https setup 74 | * Setup docker compose to use pre-built binary 75 | 76 | -------------------------------------------------------------------------------- /__modules/todo-test-data/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | todo = { 4 | source = "spkane/todo" 5 | version = "2.0.6" 6 | } 7 | } 8 | } 9 | 10 | resource "todo_todo" "first_series" { 11 | count = var.number 12 | description = "${var.team_name}-${count.index} ${var.purpose} todo" 13 | completed = false 14 | } 15 | 16 | resource "todo_todo" "second_series" { 17 | count = var.number 18 | description = "[${count.index + var.number}] ${var.descriptions[count.index]}" 19 | completed = true 20 | } 21 | 22 | -------------------------------------------------------------------------------- /__modules/todo-test-data/outputs.tf: -------------------------------------------------------------------------------- 1 | output "first_series_ids" { 2 | value = todo_todo.first_series.*.id 3 | } 4 | 5 | output "second_series_ids" { 6 | value = todo_todo.second_series.*.id 7 | } -------------------------------------------------------------------------------- /__modules/todo-test-data/variables.tf: -------------------------------------------------------------------------------- 1 | variable "number" { 2 | type = number 3 | description = "How many todos to create in each series" 4 | default = 5 5 | } 6 | 7 | variable "purpose" { 8 | type = string 9 | description = "The purpose of these todos (development, testing, integration, or production)" 10 | 11 | validation { 12 | condition = contains(["development", "testing", "integration", "production"], var.purpose) 13 | error_message = "purpose must be set to one of the following values: development, testing, integration, or production" 14 | } 15 | } 16 | 17 | variable "team_name" { 18 | type = string 19 | description = "The name of the team who created the todos" 20 | } 21 | 22 | variable "descriptions" { 23 | type = list(string) 24 | description = "A list of default descriptions" 25 | default = ["first completed test todo", 26 | "second completed test todo", 27 | "third completed test todo", 28 | "fourth completed test todo", 29 | "fifth completed test todo" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /bin/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu -o pipefail 4 | 5 | ./bin/tf_complete_build.sh 6 | docker compose build 7 | 8 | #cd terraform-provider-todo 9 | #make testacc TEST=./todo 10 | -------------------------------------------------------------------------------- /bin/package-release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | SOURCE="${BASH_SOURCE[0]}" 6 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 7 | DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" 8 | SOURCE="$(readlink "$SOURCE")" 9 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located 10 | done 11 | DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" 12 | 13 | cd "$DIR/../cmd/todo-list-server/pkg/" 14 | 15 | rm -f *.tar.gz 16 | 17 | for i in $(ls -C1 .); do 18 | cd ${i} 19 | tar -cvzf ../todo_list_server-${i}.tar.gz * 20 | cd .. 21 | done 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /bin/tests_manual.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | export TF="terraform" 6 | export OS="darwin" 7 | export ARCH="amd64" 8 | export VERSION="1.2.2" 9 | 10 | SOURCE="${BASH_SOURCE[0]}" 11 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 12 | DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" 13 | SOURCE="$(readlink "$SOURCE")" 14 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located 15 | done 16 | DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" 17 | 18 | cd "$DIR/.." 19 | ./bin/build.sh 20 | docker compose up -d 21 | # Add something to import as a data source 22 | sleep 2 23 | curl -i http://127.0.0.1:8080/ -X POST -H 'Content-Type: application/spkane.todo-list.v1+json' -d '{"description":"go shopping","completed":false}' 24 | cd terraform-tests 25 | rm -f terraform-provider-todo 26 | ${TF} init --get --upgrade=true 27 | TF_LOG=debug ${TF} apply 28 | curl -i http://127.0.0.1:8080/ 29 | docker compose down 30 | 31 | -------------------------------------------------------------------------------- /bin/tf_complete_build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # This script builds the application from source for multiple platforms. 4 | 5 | set -eu -o pipefail 6 | 7 | # Get the parent directory of where this script is. 8 | SOURCE="${BASH_SOURCE[0]}" 9 | while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done 10 | DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )" 11 | 12 | # Just force this for now... 13 | DIR1="$HOME/dev/spkane/todo-for-terraform/cmd/todo-list-server" 14 | declare -a DIRS=("${DIR1}") 15 | 16 | for DIR in "${DIRS[@]}"; do 17 | # Change into that directory 18 | cd "$DIR" 19 | APP=$(basename "${DIR}") 20 | 21 | # Get the git commit 22 | GIT_COMMIT=$(git rev-parse HEAD) 23 | GIT_DIRTY=$(test -n "`git status --porcelain`" && echo "+CHANGES" || true) 24 | 25 | # Determine the arch/os combos we're building for 26 | XC_ARCH=${XC_ARCH:-"386 amd64 arm arm64"} 27 | XC_OS=${XC_OS:-linux darwin windows freebsd openbsd solaris} 28 | XC_EXCLUDE_OSARCH="!darwin/arm !darwin/386" 29 | 30 | # Delete the old dir 31 | echo "==> Removing old bin & pkg directories in: ${DIR}..." 32 | rm -f bin/* 33 | rm -rf pkg/* 34 | mkdir -p bin/ 35 | 36 | # If its dev mode, only build for ourself 37 | set +u 38 | if [[ -z "${TF_DEV}" ]]; then 39 | TF_DEV="false" 40 | fi 41 | set -u 42 | 43 | set +u 44 | if [[ -z "${LD_FLAGS}" ]]; then 45 | LD_FLAGS="" 46 | fi 47 | set -u 48 | 49 | if [[ "${TF_DEV}" == "true" ]]; then 50 | XC_OS=$(go env GOOS) 51 | XC_ARCH=$(go env GOARCH) 52 | 53 | # Allow LD_FLAGS to be appended during development compilations 54 | 55 | LD_FLAGS="-X main.GitCommit=${GIT_COMMIT}${GIT_DIRTY} $LD_FLAGS" 56 | fi 57 | 58 | if ! which gox > /dev/null; then 59 | echo "==> Installing gox..." 60 | go get -u github.com/mitchellh/gox 61 | fi 62 | 63 | # Instruct gox to build statically linked binaries 64 | export CGO_ENABLED=0 65 | 66 | # In release mode we don't want debug information in the binary 67 | set +u 68 | if [[ -z "${TF_RELEASE}" ]]; then 69 | TF_RELEASE="false" 70 | fi 71 | set -u 72 | 73 | if [[ "${TF_RELEASE}" == "true" ]]; then 74 | LD_FLAGS="-s -w" 75 | fi 76 | 77 | # Ensure all remote modules are downloaded and cached before build so that 78 | # the concurrent builds launched by gox won't race to redundantly download them. 79 | go mod download 80 | 81 | # Build! 82 | echo "==> Building..." 83 | gox \ 84 | -os="${XC_OS}" \ 85 | -arch="${XC_ARCH}" \ 86 | -osarch="${XC_EXCLUDE_OSARCH}" \ 87 | -ldflags "${LD_FLAGS}" \ 88 | -output "pkg/{{.OS}}_{{.Arch}}/${PWD##*/}" \ 89 | . 90 | 91 | # Move all the compiled things to the $GOPATH/bin 92 | GOPATH=${GOPATH:-$(go env GOPATH)} 93 | case $(uname) in 94 | CYGWIN*) 95 | GOPATH="$(cygpath $GOPATH)" 96 | ;; 97 | esac 98 | OLDIFS=$IFS 99 | IFS=: MAIN_GOPATH=($GOPATH) 100 | IFS=$OLDIFS 101 | 102 | # Create GOPATH/bin if it's doesn't exists 103 | if [ ! -d $MAIN_GOPATH/bin ]; then 104 | echo "==> Creating GOPATH/bin directory..." 105 | mkdir -p $MAIN_GOPATH/bin 106 | fi 107 | 108 | # Copy our OS/Arch to the bin/ directory 109 | DEV_PLATFORM="./pkg/$(go env GOOS)_$(go env GOARCH)" 110 | if [[ -d "${DEV_PLATFORM}" ]]; then 111 | for F in $(find ${DEV_PLATFORM} -mindepth 1 -maxdepth 1 -type f); do 112 | cp ${F} bin/ 113 | cp ${F} ${MAIN_GOPATH}/bin/ 114 | done 115 | fi 116 | 117 | if [ "${TF_DEV}x" = "x" ]; then 118 | # Zip and copy to the dist dir 119 | echo "==> Packaging..." 120 | for PLATFORM in $(find ./pkg -mindepth 1 -maxdepth 1 -type d); do 121 | OSARCH=$(basename ${PLATFORM}) 122 | echo "--> ${OSARCH}" 123 | 124 | pushd $PLATFORM >/dev/null 2>&1 125 | zip ../${APP}-${OSARCH}.zip ./* 126 | popd >/dev/null 2>&1 127 | done 128 | fi 129 | 130 | # Done! 131 | echo 132 | echo "==> Results:" 133 | ls -hl bin/ 134 | done 135 | -------------------------------------------------------------------------------- /client/todo_list_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package client 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "github.com/go-openapi/runtime" 10 | httptransport "github.com/go-openapi/runtime/client" 11 | 12 | strfmt "github.com/go-openapi/strfmt" 13 | 14 | "github.com/spkane/todo-for-terraform/client/todos" 15 | ) 16 | 17 | // Default todo list HTTP client. 18 | var Default = NewHTTPClient(nil) 19 | 20 | const ( 21 | // DefaultHost is the default Host 22 | // found in Meta (info) section of spec file 23 | DefaultHost string = "localhost" 24 | // DefaultBasePath is the default BasePath 25 | // found in Meta (info) section of spec file 26 | DefaultBasePath string = "/" 27 | ) 28 | 29 | // DefaultSchemes are the default schemes found in Meta (info) section of spec file 30 | var DefaultSchemes = []string{"http"} 31 | 32 | // NewHTTPClient creates a new todo list HTTP client. 33 | func NewHTTPClient(formats strfmt.Registry) *TodoList { 34 | return NewHTTPClientWithConfig(formats, nil) 35 | } 36 | 37 | // NewHTTPClientWithConfig creates a new todo list HTTP client, 38 | // using a customizable transport config. 39 | func NewHTTPClientWithConfig(formats strfmt.Registry, cfg *TransportConfig) *TodoList { 40 | // ensure nullable parameters have default 41 | if cfg == nil { 42 | cfg = DefaultTransportConfig() 43 | } 44 | 45 | // create transport and client 46 | transport := httptransport.New(cfg.Host, cfg.BasePath, cfg.Schemes) 47 | return New(transport, formats) 48 | } 49 | 50 | // New creates a new todo list client 51 | func New(transport runtime.ClientTransport, formats strfmt.Registry) *TodoList { 52 | // ensure nullable parameters have default 53 | if formats == nil { 54 | formats = strfmt.Default 55 | } 56 | 57 | cli := new(TodoList) 58 | cli.Transport = transport 59 | 60 | cli.Todos = todos.New(transport, formats) 61 | 62 | return cli 63 | } 64 | 65 | // DefaultTransportConfig creates a TransportConfig with the 66 | // default settings taken from the meta section of the spec file. 67 | func DefaultTransportConfig() *TransportConfig { 68 | return &TransportConfig{ 69 | Host: DefaultHost, 70 | BasePath: DefaultBasePath, 71 | Schemes: DefaultSchemes, 72 | } 73 | } 74 | 75 | // TransportConfig contains the transport related info, 76 | // found in the meta section of the spec file. 77 | type TransportConfig struct { 78 | Host string 79 | BasePath string 80 | Schemes []string 81 | } 82 | 83 | // WithHost overrides the default host, 84 | // provided by the meta section of the spec file. 85 | func (cfg *TransportConfig) WithHost(host string) *TransportConfig { 86 | cfg.Host = host 87 | return cfg 88 | } 89 | 90 | // WithBasePath overrides the default basePath, 91 | // provided by the meta section of the spec file. 92 | func (cfg *TransportConfig) WithBasePath(basePath string) *TransportConfig { 93 | cfg.BasePath = basePath 94 | return cfg 95 | } 96 | 97 | // WithSchemes overrides the default schemes, 98 | // provided by the meta section of the spec file. 99 | func (cfg *TransportConfig) WithSchemes(schemes []string) *TransportConfig { 100 | cfg.Schemes = schemes 101 | return cfg 102 | } 103 | 104 | // TodoList is a client for todo list 105 | type TodoList struct { 106 | Todos *todos.Client 107 | 108 | Transport runtime.ClientTransport 109 | } 110 | 111 | // SetTransport changes the transport on the client and all its subresources 112 | func (c *TodoList) SetTransport(transport runtime.ClientTransport) { 113 | c.Transport = transport 114 | 115 | c.Todos.SetTransport(transport) 116 | 117 | } 118 | -------------------------------------------------------------------------------- /client/todos/add_one_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "context" 10 | "net/http" 11 | "time" 12 | 13 | "github.com/go-openapi/errors" 14 | "github.com/go-openapi/runtime" 15 | cr "github.com/go-openapi/runtime/client" 16 | 17 | strfmt "github.com/go-openapi/strfmt" 18 | 19 | models "github.com/spkane/todo-for-terraform/models" 20 | ) 21 | 22 | // NewAddOneParams creates a new AddOneParams object 23 | // with the default values initialized. 24 | func NewAddOneParams() *AddOneParams { 25 | var () 26 | return &AddOneParams{ 27 | 28 | timeout: cr.DefaultTimeout, 29 | } 30 | } 31 | 32 | // NewAddOneParamsWithTimeout creates a new AddOneParams object 33 | // with the default values initialized, and the ability to set a timeout on a request 34 | func NewAddOneParamsWithTimeout(timeout time.Duration) *AddOneParams { 35 | var () 36 | return &AddOneParams{ 37 | 38 | timeout: timeout, 39 | } 40 | } 41 | 42 | // NewAddOneParamsWithContext creates a new AddOneParams object 43 | // with the default values initialized, and the ability to set a context for a request 44 | func NewAddOneParamsWithContext(ctx context.Context) *AddOneParams { 45 | var () 46 | return &AddOneParams{ 47 | 48 | Context: ctx, 49 | } 50 | } 51 | 52 | // NewAddOneParamsWithHTTPClient creates a new AddOneParams object 53 | // with the default values initialized, and the ability to set a custom HTTPClient for a request 54 | func NewAddOneParamsWithHTTPClient(client *http.Client) *AddOneParams { 55 | var () 56 | return &AddOneParams{ 57 | HTTPClient: client, 58 | } 59 | } 60 | 61 | /*AddOneParams contains all the parameters to send to the API endpoint 62 | for the add one operation typically these are written to a http.Request 63 | */ 64 | type AddOneParams struct { 65 | 66 | /*Body*/ 67 | Body *models.Item 68 | 69 | timeout time.Duration 70 | Context context.Context 71 | HTTPClient *http.Client 72 | } 73 | 74 | // WithTimeout adds the timeout to the add one params 75 | func (o *AddOneParams) WithTimeout(timeout time.Duration) *AddOneParams { 76 | o.SetTimeout(timeout) 77 | return o 78 | } 79 | 80 | // SetTimeout adds the timeout to the add one params 81 | func (o *AddOneParams) SetTimeout(timeout time.Duration) { 82 | o.timeout = timeout 83 | } 84 | 85 | // WithContext adds the context to the add one params 86 | func (o *AddOneParams) WithContext(ctx context.Context) *AddOneParams { 87 | o.SetContext(ctx) 88 | return o 89 | } 90 | 91 | // SetContext adds the context to the add one params 92 | func (o *AddOneParams) SetContext(ctx context.Context) { 93 | o.Context = ctx 94 | } 95 | 96 | // WithHTTPClient adds the HTTPClient to the add one params 97 | func (o *AddOneParams) WithHTTPClient(client *http.Client) *AddOneParams { 98 | o.SetHTTPClient(client) 99 | return o 100 | } 101 | 102 | // SetHTTPClient adds the HTTPClient to the add one params 103 | func (o *AddOneParams) SetHTTPClient(client *http.Client) { 104 | o.HTTPClient = client 105 | } 106 | 107 | // WithBody adds the body to the add one params 108 | func (o *AddOneParams) WithBody(body *models.Item) *AddOneParams { 109 | o.SetBody(body) 110 | return o 111 | } 112 | 113 | // SetBody adds the body to the add one params 114 | func (o *AddOneParams) SetBody(body *models.Item) { 115 | o.Body = body 116 | } 117 | 118 | // WriteToRequest writes these params to a swagger request 119 | func (o *AddOneParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { 120 | 121 | if err := r.SetTimeout(o.timeout); err != nil { 122 | return err 123 | } 124 | var res []error 125 | 126 | if o.Body != nil { 127 | if err := r.SetBodyParam(o.Body); err != nil { 128 | return err 129 | } 130 | } 131 | 132 | if len(res) > 0 { 133 | return errors.CompositeValidationError(res...) 134 | } 135 | return nil 136 | } 137 | -------------------------------------------------------------------------------- /client/todos/add_one_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | 12 | "github.com/go-openapi/runtime" 13 | 14 | strfmt "github.com/go-openapi/strfmt" 15 | 16 | models "github.com/spkane/todo-for-terraform/models" 17 | ) 18 | 19 | // AddOneReader is a Reader for the AddOne structure. 20 | type AddOneReader struct { 21 | formats strfmt.Registry 22 | } 23 | 24 | // ReadResponse reads a server response into the received o. 25 | func (o *AddOneReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { 26 | switch response.Code() { 27 | case 201: 28 | result := NewAddOneCreated() 29 | if err := result.readResponse(response, consumer, o.formats); err != nil { 30 | return nil, err 31 | } 32 | return result, nil 33 | default: 34 | result := NewAddOneDefault(response.Code()) 35 | if err := result.readResponse(response, consumer, o.formats); err != nil { 36 | return nil, err 37 | } 38 | if response.Code()/100 == 2 { 39 | return result, nil 40 | } 41 | return nil, result 42 | } 43 | } 44 | 45 | // NewAddOneCreated creates a AddOneCreated with default headers values 46 | func NewAddOneCreated() *AddOneCreated { 47 | return &AddOneCreated{} 48 | } 49 | 50 | /*AddOneCreated handles this case with default header values. 51 | 52 | Created 53 | */ 54 | type AddOneCreated struct { 55 | Payload *models.Item 56 | } 57 | 58 | func (o *AddOneCreated) Error() string { 59 | return fmt.Sprintf("[POST /][%d] addOneCreated %+v", 201, o.Payload) 60 | } 61 | 62 | func (o *AddOneCreated) GetPayload() *models.Item { 63 | return o.Payload 64 | } 65 | 66 | func (o *AddOneCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 67 | 68 | o.Payload = new(models.Item) 69 | 70 | // response payload 71 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { 72 | return err 73 | } 74 | 75 | return nil 76 | } 77 | 78 | // NewAddOneDefault creates a AddOneDefault with default headers values 79 | func NewAddOneDefault(code int) *AddOneDefault { 80 | return &AddOneDefault{ 81 | _statusCode: code, 82 | } 83 | } 84 | 85 | /*AddOneDefault handles this case with default header values. 86 | 87 | error 88 | */ 89 | type AddOneDefault struct { 90 | _statusCode int 91 | 92 | Payload *models.Error 93 | } 94 | 95 | // Code gets the status code for the add one default response 96 | func (o *AddOneDefault) Code() int { 97 | return o._statusCode 98 | } 99 | 100 | func (o *AddOneDefault) Error() string { 101 | return fmt.Sprintf("[POST /][%d] addOne default %+v", o._statusCode, o.Payload) 102 | } 103 | 104 | func (o *AddOneDefault) GetPayload() *models.Error { 105 | return o.Payload 106 | } 107 | 108 | func (o *AddOneDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 109 | 110 | o.Payload = new(models.Error) 111 | 112 | // response payload 113 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { 114 | return err 115 | } 116 | 117 | return nil 118 | } 119 | -------------------------------------------------------------------------------- /client/todos/destroy_one_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "context" 10 | "net/http" 11 | "time" 12 | 13 | "github.com/go-openapi/errors" 14 | "github.com/go-openapi/runtime" 15 | cr "github.com/go-openapi/runtime/client" 16 | "github.com/go-openapi/swag" 17 | 18 | strfmt "github.com/go-openapi/strfmt" 19 | ) 20 | 21 | // NewDestroyOneParams creates a new DestroyOneParams object 22 | // with the default values initialized. 23 | func NewDestroyOneParams() *DestroyOneParams { 24 | var () 25 | return &DestroyOneParams{ 26 | 27 | timeout: cr.DefaultTimeout, 28 | } 29 | } 30 | 31 | // NewDestroyOneParamsWithTimeout creates a new DestroyOneParams object 32 | // with the default values initialized, and the ability to set a timeout on a request 33 | func NewDestroyOneParamsWithTimeout(timeout time.Duration) *DestroyOneParams { 34 | var () 35 | return &DestroyOneParams{ 36 | 37 | timeout: timeout, 38 | } 39 | } 40 | 41 | // NewDestroyOneParamsWithContext creates a new DestroyOneParams object 42 | // with the default values initialized, and the ability to set a context for a request 43 | func NewDestroyOneParamsWithContext(ctx context.Context) *DestroyOneParams { 44 | var () 45 | return &DestroyOneParams{ 46 | 47 | Context: ctx, 48 | } 49 | } 50 | 51 | // NewDestroyOneParamsWithHTTPClient creates a new DestroyOneParams object 52 | // with the default values initialized, and the ability to set a custom HTTPClient for a request 53 | func NewDestroyOneParamsWithHTTPClient(client *http.Client) *DestroyOneParams { 54 | var () 55 | return &DestroyOneParams{ 56 | HTTPClient: client, 57 | } 58 | } 59 | 60 | /*DestroyOneParams contains all the parameters to send to the API endpoint 61 | for the destroy one operation typically these are written to a http.Request 62 | */ 63 | type DestroyOneParams struct { 64 | 65 | /*ID*/ 66 | ID int64 67 | 68 | timeout time.Duration 69 | Context context.Context 70 | HTTPClient *http.Client 71 | } 72 | 73 | // WithTimeout adds the timeout to the destroy one params 74 | func (o *DestroyOneParams) WithTimeout(timeout time.Duration) *DestroyOneParams { 75 | o.SetTimeout(timeout) 76 | return o 77 | } 78 | 79 | // SetTimeout adds the timeout to the destroy one params 80 | func (o *DestroyOneParams) SetTimeout(timeout time.Duration) { 81 | o.timeout = timeout 82 | } 83 | 84 | // WithContext adds the context to the destroy one params 85 | func (o *DestroyOneParams) WithContext(ctx context.Context) *DestroyOneParams { 86 | o.SetContext(ctx) 87 | return o 88 | } 89 | 90 | // SetContext adds the context to the destroy one params 91 | func (o *DestroyOneParams) SetContext(ctx context.Context) { 92 | o.Context = ctx 93 | } 94 | 95 | // WithHTTPClient adds the HTTPClient to the destroy one params 96 | func (o *DestroyOneParams) WithHTTPClient(client *http.Client) *DestroyOneParams { 97 | o.SetHTTPClient(client) 98 | return o 99 | } 100 | 101 | // SetHTTPClient adds the HTTPClient to the destroy one params 102 | func (o *DestroyOneParams) SetHTTPClient(client *http.Client) { 103 | o.HTTPClient = client 104 | } 105 | 106 | // WithID adds the id to the destroy one params 107 | func (o *DestroyOneParams) WithID(id int64) *DestroyOneParams { 108 | o.SetID(id) 109 | return o 110 | } 111 | 112 | // SetID adds the id to the destroy one params 113 | func (o *DestroyOneParams) SetID(id int64) { 114 | o.ID = id 115 | } 116 | 117 | // WriteToRequest writes these params to a swagger request 118 | func (o *DestroyOneParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { 119 | 120 | if err := r.SetTimeout(o.timeout); err != nil { 121 | return err 122 | } 123 | var res []error 124 | 125 | // path param id 126 | if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil { 127 | return err 128 | } 129 | 130 | if len(res) > 0 { 131 | return errors.CompositeValidationError(res...) 132 | } 133 | return nil 134 | } 135 | -------------------------------------------------------------------------------- /client/todos/destroy_one_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | 12 | "github.com/go-openapi/runtime" 13 | 14 | strfmt "github.com/go-openapi/strfmt" 15 | 16 | models "github.com/spkane/todo-for-terraform/models" 17 | ) 18 | 19 | // DestroyOneReader is a Reader for the DestroyOne structure. 20 | type DestroyOneReader struct { 21 | formats strfmt.Registry 22 | } 23 | 24 | // ReadResponse reads a server response into the received o. 25 | func (o *DestroyOneReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { 26 | switch response.Code() { 27 | case 204: 28 | result := NewDestroyOneNoContent() 29 | if err := result.readResponse(response, consumer, o.formats); err != nil { 30 | return nil, err 31 | } 32 | return result, nil 33 | default: 34 | result := NewDestroyOneDefault(response.Code()) 35 | if err := result.readResponse(response, consumer, o.formats); err != nil { 36 | return nil, err 37 | } 38 | if response.Code()/100 == 2 { 39 | return result, nil 40 | } 41 | return nil, result 42 | } 43 | } 44 | 45 | // NewDestroyOneNoContent creates a DestroyOneNoContent with default headers values 46 | func NewDestroyOneNoContent() *DestroyOneNoContent { 47 | return &DestroyOneNoContent{} 48 | } 49 | 50 | /*DestroyOneNoContent handles this case with default header values. 51 | 52 | Deleted 53 | */ 54 | type DestroyOneNoContent struct { 55 | } 56 | 57 | func (o *DestroyOneNoContent) Error() string { 58 | return fmt.Sprintf("[DELETE /{id}][%d] destroyOneNoContent ", 204) 59 | } 60 | 61 | func (o *DestroyOneNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 62 | 63 | return nil 64 | } 65 | 66 | // NewDestroyOneDefault creates a DestroyOneDefault with default headers values 67 | func NewDestroyOneDefault(code int) *DestroyOneDefault { 68 | return &DestroyOneDefault{ 69 | _statusCode: code, 70 | } 71 | } 72 | 73 | /*DestroyOneDefault handles this case with default header values. 74 | 75 | error 76 | */ 77 | type DestroyOneDefault struct { 78 | _statusCode int 79 | 80 | Payload *models.Error 81 | } 82 | 83 | // Code gets the status code for the destroy one default response 84 | func (o *DestroyOneDefault) Code() int { 85 | return o._statusCode 86 | } 87 | 88 | func (o *DestroyOneDefault) Error() string { 89 | return fmt.Sprintf("[DELETE /{id}][%d] destroyOne default %+v", o._statusCode, o.Payload) 90 | } 91 | 92 | func (o *DestroyOneDefault) GetPayload() *models.Error { 93 | return o.Payload 94 | } 95 | 96 | func (o *DestroyOneDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 97 | 98 | o.Payload = new(models.Error) 99 | 100 | // response payload 101 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { 102 | return err 103 | } 104 | 105 | return nil 106 | } 107 | -------------------------------------------------------------------------------- /client/todos/find_todo_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "context" 10 | "net/http" 11 | "time" 12 | 13 | "github.com/go-openapi/errors" 14 | "github.com/go-openapi/runtime" 15 | cr "github.com/go-openapi/runtime/client" 16 | "github.com/go-openapi/swag" 17 | 18 | strfmt "github.com/go-openapi/strfmt" 19 | ) 20 | 21 | // NewFindTodoParams creates a new FindTodoParams object 22 | // with the default values initialized. 23 | func NewFindTodoParams() *FindTodoParams { 24 | var () 25 | return &FindTodoParams{ 26 | 27 | timeout: cr.DefaultTimeout, 28 | } 29 | } 30 | 31 | // NewFindTodoParamsWithTimeout creates a new FindTodoParams object 32 | // with the default values initialized, and the ability to set a timeout on a request 33 | func NewFindTodoParamsWithTimeout(timeout time.Duration) *FindTodoParams { 34 | var () 35 | return &FindTodoParams{ 36 | 37 | timeout: timeout, 38 | } 39 | } 40 | 41 | // NewFindTodoParamsWithContext creates a new FindTodoParams object 42 | // with the default values initialized, and the ability to set a context for a request 43 | func NewFindTodoParamsWithContext(ctx context.Context) *FindTodoParams { 44 | var () 45 | return &FindTodoParams{ 46 | 47 | Context: ctx, 48 | } 49 | } 50 | 51 | // NewFindTodoParamsWithHTTPClient creates a new FindTodoParams object 52 | // with the default values initialized, and the ability to set a custom HTTPClient for a request 53 | func NewFindTodoParamsWithHTTPClient(client *http.Client) *FindTodoParams { 54 | var () 55 | return &FindTodoParams{ 56 | HTTPClient: client, 57 | } 58 | } 59 | 60 | /*FindTodoParams contains all the parameters to send to the API endpoint 61 | for the find todo operation typically these are written to a http.Request 62 | */ 63 | type FindTodoParams struct { 64 | 65 | /*ID*/ 66 | ID int64 67 | 68 | timeout time.Duration 69 | Context context.Context 70 | HTTPClient *http.Client 71 | } 72 | 73 | // WithTimeout adds the timeout to the find todo params 74 | func (o *FindTodoParams) WithTimeout(timeout time.Duration) *FindTodoParams { 75 | o.SetTimeout(timeout) 76 | return o 77 | } 78 | 79 | // SetTimeout adds the timeout to the find todo params 80 | func (o *FindTodoParams) SetTimeout(timeout time.Duration) { 81 | o.timeout = timeout 82 | } 83 | 84 | // WithContext adds the context to the find todo params 85 | func (o *FindTodoParams) WithContext(ctx context.Context) *FindTodoParams { 86 | o.SetContext(ctx) 87 | return o 88 | } 89 | 90 | // SetContext adds the context to the find todo params 91 | func (o *FindTodoParams) SetContext(ctx context.Context) { 92 | o.Context = ctx 93 | } 94 | 95 | // WithHTTPClient adds the HTTPClient to the find todo params 96 | func (o *FindTodoParams) WithHTTPClient(client *http.Client) *FindTodoParams { 97 | o.SetHTTPClient(client) 98 | return o 99 | } 100 | 101 | // SetHTTPClient adds the HTTPClient to the find todo params 102 | func (o *FindTodoParams) SetHTTPClient(client *http.Client) { 103 | o.HTTPClient = client 104 | } 105 | 106 | // WithID adds the id to the find todo params 107 | func (o *FindTodoParams) WithID(id int64) *FindTodoParams { 108 | o.SetID(id) 109 | return o 110 | } 111 | 112 | // SetID adds the id to the find todo params 113 | func (o *FindTodoParams) SetID(id int64) { 114 | o.ID = id 115 | } 116 | 117 | // WriteToRequest writes these params to a swagger request 118 | func (o *FindTodoParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { 119 | 120 | if err := r.SetTimeout(o.timeout); err != nil { 121 | return err 122 | } 123 | var res []error 124 | 125 | // path param id 126 | if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil { 127 | return err 128 | } 129 | 130 | if len(res) > 0 { 131 | return errors.CompositeValidationError(res...) 132 | } 133 | return nil 134 | } 135 | -------------------------------------------------------------------------------- /client/todos/find_todo_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | 12 | "github.com/go-openapi/runtime" 13 | 14 | strfmt "github.com/go-openapi/strfmt" 15 | 16 | models "github.com/spkane/todo-for-terraform/models" 17 | ) 18 | 19 | // FindTodoReader is a Reader for the FindTodo structure. 20 | type FindTodoReader struct { 21 | formats strfmt.Registry 22 | } 23 | 24 | // ReadResponse reads a server response into the received o. 25 | func (o *FindTodoReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { 26 | switch response.Code() { 27 | case 200: 28 | result := NewFindTodoOK() 29 | if err := result.readResponse(response, consumer, o.formats); err != nil { 30 | return nil, err 31 | } 32 | return result, nil 33 | default: 34 | result := NewFindTodoDefault(response.Code()) 35 | if err := result.readResponse(response, consumer, o.formats); err != nil { 36 | return nil, err 37 | } 38 | if response.Code()/100 == 2 { 39 | return result, nil 40 | } 41 | return nil, result 42 | } 43 | } 44 | 45 | // NewFindTodoOK creates a FindTodoOK with default headers values 46 | func NewFindTodoOK() *FindTodoOK { 47 | return &FindTodoOK{} 48 | } 49 | 50 | /*FindTodoOK handles this case with default header values. 51 | 52 | list the todo 53 | */ 54 | type FindTodoOK struct { 55 | Payload []*models.Item 56 | } 57 | 58 | func (o *FindTodoOK) Error() string { 59 | return fmt.Sprintf("[GET /{id}][%d] findTodoOK %+v", 200, o.Payload) 60 | } 61 | 62 | func (o *FindTodoOK) GetPayload() []*models.Item { 63 | return o.Payload 64 | } 65 | 66 | func (o *FindTodoOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 67 | 68 | // response payload 69 | if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { 70 | return err 71 | } 72 | 73 | return nil 74 | } 75 | 76 | // NewFindTodoDefault creates a FindTodoDefault with default headers values 77 | func NewFindTodoDefault(code int) *FindTodoDefault { 78 | return &FindTodoDefault{ 79 | _statusCode: code, 80 | } 81 | } 82 | 83 | /*FindTodoDefault handles this case with default header values. 84 | 85 | generic error response 86 | */ 87 | type FindTodoDefault struct { 88 | _statusCode int 89 | 90 | Payload *models.Error 91 | } 92 | 93 | // Code gets the status code for the find todo default response 94 | func (o *FindTodoDefault) Code() int { 95 | return o._statusCode 96 | } 97 | 98 | func (o *FindTodoDefault) Error() string { 99 | return fmt.Sprintf("[GET /{id}][%d] findTodo default %+v", o._statusCode, o.Payload) 100 | } 101 | 102 | func (o *FindTodoDefault) GetPayload() *models.Error { 103 | return o.Payload 104 | } 105 | 106 | func (o *FindTodoDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 107 | 108 | o.Payload = new(models.Error) 109 | 110 | // response payload 111 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { 112 | return err 113 | } 114 | 115 | return nil 116 | } 117 | -------------------------------------------------------------------------------- /client/todos/find_todos_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "context" 10 | "net/http" 11 | "time" 12 | 13 | "github.com/go-openapi/errors" 14 | "github.com/go-openapi/runtime" 15 | cr "github.com/go-openapi/runtime/client" 16 | "github.com/go-openapi/swag" 17 | 18 | strfmt "github.com/go-openapi/strfmt" 19 | ) 20 | 21 | // NewFindTodosParams creates a new FindTodosParams object 22 | // with the default values initialized. 23 | func NewFindTodosParams() *FindTodosParams { 24 | var ( 25 | limitDefault = int32(20) 26 | ) 27 | return &FindTodosParams{ 28 | Limit: &limitDefault, 29 | 30 | timeout: cr.DefaultTimeout, 31 | } 32 | } 33 | 34 | // NewFindTodosParamsWithTimeout creates a new FindTodosParams object 35 | // with the default values initialized, and the ability to set a timeout on a request 36 | func NewFindTodosParamsWithTimeout(timeout time.Duration) *FindTodosParams { 37 | var ( 38 | limitDefault = int32(20) 39 | ) 40 | return &FindTodosParams{ 41 | Limit: &limitDefault, 42 | 43 | timeout: timeout, 44 | } 45 | } 46 | 47 | // NewFindTodosParamsWithContext creates a new FindTodosParams object 48 | // with the default values initialized, and the ability to set a context for a request 49 | func NewFindTodosParamsWithContext(ctx context.Context) *FindTodosParams { 50 | var ( 51 | limitDefault = int32(20) 52 | ) 53 | return &FindTodosParams{ 54 | Limit: &limitDefault, 55 | 56 | Context: ctx, 57 | } 58 | } 59 | 60 | // NewFindTodosParamsWithHTTPClient creates a new FindTodosParams object 61 | // with the default values initialized, and the ability to set a custom HTTPClient for a request 62 | func NewFindTodosParamsWithHTTPClient(client *http.Client) *FindTodosParams { 63 | var ( 64 | limitDefault = int32(20) 65 | ) 66 | return &FindTodosParams{ 67 | Limit: &limitDefault, 68 | HTTPClient: client, 69 | } 70 | } 71 | 72 | /*FindTodosParams contains all the parameters to send to the API endpoint 73 | for the find todos operation typically these are written to a http.Request 74 | */ 75 | type FindTodosParams struct { 76 | 77 | /*Limit*/ 78 | Limit *int32 79 | /*Since*/ 80 | Since *int64 81 | 82 | timeout time.Duration 83 | Context context.Context 84 | HTTPClient *http.Client 85 | } 86 | 87 | // WithTimeout adds the timeout to the find todos params 88 | func (o *FindTodosParams) WithTimeout(timeout time.Duration) *FindTodosParams { 89 | o.SetTimeout(timeout) 90 | return o 91 | } 92 | 93 | // SetTimeout adds the timeout to the find todos params 94 | func (o *FindTodosParams) SetTimeout(timeout time.Duration) { 95 | o.timeout = timeout 96 | } 97 | 98 | // WithContext adds the context to the find todos params 99 | func (o *FindTodosParams) WithContext(ctx context.Context) *FindTodosParams { 100 | o.SetContext(ctx) 101 | return o 102 | } 103 | 104 | // SetContext adds the context to the find todos params 105 | func (o *FindTodosParams) SetContext(ctx context.Context) { 106 | o.Context = ctx 107 | } 108 | 109 | // WithHTTPClient adds the HTTPClient to the find todos params 110 | func (o *FindTodosParams) WithHTTPClient(client *http.Client) *FindTodosParams { 111 | o.SetHTTPClient(client) 112 | return o 113 | } 114 | 115 | // SetHTTPClient adds the HTTPClient to the find todos params 116 | func (o *FindTodosParams) SetHTTPClient(client *http.Client) { 117 | o.HTTPClient = client 118 | } 119 | 120 | // WithLimit adds the limit to the find todos params 121 | func (o *FindTodosParams) WithLimit(limit *int32) *FindTodosParams { 122 | o.SetLimit(limit) 123 | return o 124 | } 125 | 126 | // SetLimit adds the limit to the find todos params 127 | func (o *FindTodosParams) SetLimit(limit *int32) { 128 | o.Limit = limit 129 | } 130 | 131 | // WithSince adds the since to the find todos params 132 | func (o *FindTodosParams) WithSince(since *int64) *FindTodosParams { 133 | o.SetSince(since) 134 | return o 135 | } 136 | 137 | // SetSince adds the since to the find todos params 138 | func (o *FindTodosParams) SetSince(since *int64) { 139 | o.Since = since 140 | } 141 | 142 | // WriteToRequest writes these params to a swagger request 143 | func (o *FindTodosParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { 144 | 145 | if err := r.SetTimeout(o.timeout); err != nil { 146 | return err 147 | } 148 | var res []error 149 | 150 | if o.Limit != nil { 151 | 152 | // query param limit 153 | var qrLimit int32 154 | if o.Limit != nil { 155 | qrLimit = *o.Limit 156 | } 157 | qLimit := swag.FormatInt32(qrLimit) 158 | if qLimit != "" { 159 | if err := r.SetQueryParam("limit", qLimit); err != nil { 160 | return err 161 | } 162 | } 163 | 164 | } 165 | 166 | if o.Since != nil { 167 | 168 | // query param since 169 | var qrSince int64 170 | if o.Since != nil { 171 | qrSince = *o.Since 172 | } 173 | qSince := swag.FormatInt64(qrSince) 174 | if qSince != "" { 175 | if err := r.SetQueryParam("since", qSince); err != nil { 176 | return err 177 | } 178 | } 179 | 180 | } 181 | 182 | if len(res) > 0 { 183 | return errors.CompositeValidationError(res...) 184 | } 185 | return nil 186 | } 187 | -------------------------------------------------------------------------------- /client/todos/find_todos_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | 12 | "github.com/go-openapi/runtime" 13 | 14 | strfmt "github.com/go-openapi/strfmt" 15 | 16 | models "github.com/spkane/todo-for-terraform/models" 17 | ) 18 | 19 | // FindTodosReader is a Reader for the FindTodos structure. 20 | type FindTodosReader struct { 21 | formats strfmt.Registry 22 | } 23 | 24 | // ReadResponse reads a server response into the received o. 25 | func (o *FindTodosReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { 26 | switch response.Code() { 27 | case 200: 28 | result := NewFindTodosOK() 29 | if err := result.readResponse(response, consumer, o.formats); err != nil { 30 | return nil, err 31 | } 32 | return result, nil 33 | default: 34 | result := NewFindTodosDefault(response.Code()) 35 | if err := result.readResponse(response, consumer, o.formats); err != nil { 36 | return nil, err 37 | } 38 | if response.Code()/100 == 2 { 39 | return result, nil 40 | } 41 | return nil, result 42 | } 43 | } 44 | 45 | // NewFindTodosOK creates a FindTodosOK with default headers values 46 | func NewFindTodosOK() *FindTodosOK { 47 | return &FindTodosOK{} 48 | } 49 | 50 | /*FindTodosOK handles this case with default header values. 51 | 52 | list the todo operations 53 | */ 54 | type FindTodosOK struct { 55 | Payload []*models.Item 56 | } 57 | 58 | func (o *FindTodosOK) Error() string { 59 | return fmt.Sprintf("[GET /][%d] findTodosOK %+v", 200, o.Payload) 60 | } 61 | 62 | func (o *FindTodosOK) GetPayload() []*models.Item { 63 | return o.Payload 64 | } 65 | 66 | func (o *FindTodosOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 67 | 68 | // response payload 69 | if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF { 70 | return err 71 | } 72 | 73 | return nil 74 | } 75 | 76 | // NewFindTodosDefault creates a FindTodosDefault with default headers values 77 | func NewFindTodosDefault(code int) *FindTodosDefault { 78 | return &FindTodosDefault{ 79 | _statusCode: code, 80 | } 81 | } 82 | 83 | /*FindTodosDefault handles this case with default header values. 84 | 85 | generic error response 86 | */ 87 | type FindTodosDefault struct { 88 | _statusCode int 89 | 90 | Payload *models.Error 91 | } 92 | 93 | // Code gets the status code for the find todos default response 94 | func (o *FindTodosDefault) Code() int { 95 | return o._statusCode 96 | } 97 | 98 | func (o *FindTodosDefault) Error() string { 99 | return fmt.Sprintf("[GET /][%d] findTodos default %+v", o._statusCode, o.Payload) 100 | } 101 | 102 | func (o *FindTodosDefault) GetPayload() *models.Error { 103 | return o.Payload 104 | } 105 | 106 | func (o *FindTodosDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 107 | 108 | o.Payload = new(models.Error) 109 | 110 | // response payload 111 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { 112 | return err 113 | } 114 | 115 | return nil 116 | } 117 | -------------------------------------------------------------------------------- /client/todos/todos_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "github.com/go-openapi/runtime" 10 | 11 | strfmt "github.com/go-openapi/strfmt" 12 | ) 13 | 14 | // New creates a new todos API client. 15 | func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client { 16 | return &Client{transport: transport, formats: formats} 17 | } 18 | 19 | /* 20 | Client for todos API 21 | */ 22 | type Client struct { 23 | transport runtime.ClientTransport 24 | formats strfmt.Registry 25 | } 26 | 27 | /* 28 | AddOne add one API 29 | */ 30 | func (a *Client) AddOne(params *AddOneParams) (*AddOneCreated, error) { 31 | // TODO: Validate the params before sending 32 | if params == nil { 33 | params = NewAddOneParams() 34 | } 35 | 36 | result, err := a.transport.Submit(&runtime.ClientOperation{ 37 | ID: "addOne", 38 | Method: "POST", 39 | PathPattern: "/", 40 | ProducesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 41 | ConsumesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 42 | Schemes: []string{"http"}, 43 | Params: params, 44 | Reader: &AddOneReader{formats: a.formats}, 45 | Context: params.Context, 46 | Client: params.HTTPClient, 47 | }) 48 | if err != nil { 49 | return nil, err 50 | } 51 | success, ok := result.(*AddOneCreated) 52 | if ok { 53 | return success, nil 54 | } 55 | // unexpected success response 56 | unexpectedSuccess := result.(*AddOneDefault) 57 | return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) 58 | } 59 | 60 | /* 61 | DestroyOne destroy one API 62 | */ 63 | func (a *Client) DestroyOne(params *DestroyOneParams) (*DestroyOneNoContent, error) { 64 | // TODO: Validate the params before sending 65 | if params == nil { 66 | params = NewDestroyOneParams() 67 | } 68 | 69 | result, err := a.transport.Submit(&runtime.ClientOperation{ 70 | ID: "destroyOne", 71 | Method: "DELETE", 72 | PathPattern: "/{id}", 73 | ProducesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 74 | ConsumesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 75 | Schemes: []string{"http"}, 76 | Params: params, 77 | Reader: &DestroyOneReader{formats: a.formats}, 78 | Context: params.Context, 79 | Client: params.HTTPClient, 80 | }) 81 | if err != nil { 82 | return nil, err 83 | } 84 | success, ok := result.(*DestroyOneNoContent) 85 | if ok { 86 | return success, nil 87 | } 88 | // unexpected success response 89 | unexpectedSuccess := result.(*DestroyOneDefault) 90 | return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) 91 | } 92 | 93 | /* 94 | FindTodo find todo API 95 | */ 96 | func (a *Client) FindTodo(params *FindTodoParams) (*FindTodoOK, error) { 97 | // TODO: Validate the params before sending 98 | if params == nil { 99 | params = NewFindTodoParams() 100 | } 101 | 102 | result, err := a.transport.Submit(&runtime.ClientOperation{ 103 | ID: "findTodo", 104 | Method: "GET", 105 | PathPattern: "/{id}", 106 | ProducesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 107 | ConsumesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 108 | Schemes: []string{"http"}, 109 | Params: params, 110 | Reader: &FindTodoReader{formats: a.formats}, 111 | Context: params.Context, 112 | Client: params.HTTPClient, 113 | }) 114 | if err != nil { 115 | return nil, err 116 | } 117 | success, ok := result.(*FindTodoOK) 118 | if ok { 119 | return success, nil 120 | } 121 | // unexpected success response 122 | unexpectedSuccess := result.(*FindTodoDefault) 123 | return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) 124 | } 125 | 126 | /* 127 | FindTodos find todos API 128 | */ 129 | func (a *Client) FindTodos(params *FindTodosParams) (*FindTodosOK, error) { 130 | // TODO: Validate the params before sending 131 | if params == nil { 132 | params = NewFindTodosParams() 133 | } 134 | 135 | result, err := a.transport.Submit(&runtime.ClientOperation{ 136 | ID: "findTodos", 137 | Method: "GET", 138 | PathPattern: "/", 139 | ProducesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 140 | ConsumesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 141 | Schemes: []string{"http"}, 142 | Params: params, 143 | Reader: &FindTodosReader{formats: a.formats}, 144 | Context: params.Context, 145 | Client: params.HTTPClient, 146 | }) 147 | if err != nil { 148 | return nil, err 149 | } 150 | success, ok := result.(*FindTodosOK) 151 | if ok { 152 | return success, nil 153 | } 154 | // unexpected success response 155 | unexpectedSuccess := result.(*FindTodosDefault) 156 | return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) 157 | } 158 | 159 | /* 160 | UpdateOne update one API 161 | */ 162 | func (a *Client) UpdateOne(params *UpdateOneParams) (*UpdateOneOK, error) { 163 | // TODO: Validate the params before sending 164 | if params == nil { 165 | params = NewUpdateOneParams() 166 | } 167 | 168 | result, err := a.transport.Submit(&runtime.ClientOperation{ 169 | ID: "updateOne", 170 | Method: "PUT", 171 | PathPattern: "/{id}", 172 | ProducesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 173 | ConsumesMediaTypes: []string{"application/spkane.todo-list.v1+json"}, 174 | Schemes: []string{"http"}, 175 | Params: params, 176 | Reader: &UpdateOneReader{formats: a.formats}, 177 | Context: params.Context, 178 | Client: params.HTTPClient, 179 | }) 180 | if err != nil { 181 | return nil, err 182 | } 183 | success, ok := result.(*UpdateOneOK) 184 | if ok { 185 | return success, nil 186 | } 187 | // unexpected success response 188 | unexpectedSuccess := result.(*UpdateOneDefault) 189 | return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) 190 | } 191 | 192 | // SetTransport changes the transport on the client 193 | func (a *Client) SetTransport(transport runtime.ClientTransport) { 194 | a.transport = transport 195 | } 196 | -------------------------------------------------------------------------------- /client/todos/update_one_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "context" 10 | "net/http" 11 | "time" 12 | 13 | "github.com/go-openapi/errors" 14 | "github.com/go-openapi/runtime" 15 | cr "github.com/go-openapi/runtime/client" 16 | "github.com/go-openapi/swag" 17 | 18 | strfmt "github.com/go-openapi/strfmt" 19 | 20 | models "github.com/spkane/todo-for-terraform/models" 21 | ) 22 | 23 | // NewUpdateOneParams creates a new UpdateOneParams object 24 | // with the default values initialized. 25 | func NewUpdateOneParams() *UpdateOneParams { 26 | var () 27 | return &UpdateOneParams{ 28 | 29 | timeout: cr.DefaultTimeout, 30 | } 31 | } 32 | 33 | // NewUpdateOneParamsWithTimeout creates a new UpdateOneParams object 34 | // with the default values initialized, and the ability to set a timeout on a request 35 | func NewUpdateOneParamsWithTimeout(timeout time.Duration) *UpdateOneParams { 36 | var () 37 | return &UpdateOneParams{ 38 | 39 | timeout: timeout, 40 | } 41 | } 42 | 43 | // NewUpdateOneParamsWithContext creates a new UpdateOneParams object 44 | // with the default values initialized, and the ability to set a context for a request 45 | func NewUpdateOneParamsWithContext(ctx context.Context) *UpdateOneParams { 46 | var () 47 | return &UpdateOneParams{ 48 | 49 | Context: ctx, 50 | } 51 | } 52 | 53 | // NewUpdateOneParamsWithHTTPClient creates a new UpdateOneParams object 54 | // with the default values initialized, and the ability to set a custom HTTPClient for a request 55 | func NewUpdateOneParamsWithHTTPClient(client *http.Client) *UpdateOneParams { 56 | var () 57 | return &UpdateOneParams{ 58 | HTTPClient: client, 59 | } 60 | } 61 | 62 | /*UpdateOneParams contains all the parameters to send to the API endpoint 63 | for the update one operation typically these are written to a http.Request 64 | */ 65 | type UpdateOneParams struct { 66 | 67 | /*Body*/ 68 | Body *models.Item 69 | /*ID*/ 70 | ID int64 71 | 72 | timeout time.Duration 73 | Context context.Context 74 | HTTPClient *http.Client 75 | } 76 | 77 | // WithTimeout adds the timeout to the update one params 78 | func (o *UpdateOneParams) WithTimeout(timeout time.Duration) *UpdateOneParams { 79 | o.SetTimeout(timeout) 80 | return o 81 | } 82 | 83 | // SetTimeout adds the timeout to the update one params 84 | func (o *UpdateOneParams) SetTimeout(timeout time.Duration) { 85 | o.timeout = timeout 86 | } 87 | 88 | // WithContext adds the context to the update one params 89 | func (o *UpdateOneParams) WithContext(ctx context.Context) *UpdateOneParams { 90 | o.SetContext(ctx) 91 | return o 92 | } 93 | 94 | // SetContext adds the context to the update one params 95 | func (o *UpdateOneParams) SetContext(ctx context.Context) { 96 | o.Context = ctx 97 | } 98 | 99 | // WithHTTPClient adds the HTTPClient to the update one params 100 | func (o *UpdateOneParams) WithHTTPClient(client *http.Client) *UpdateOneParams { 101 | o.SetHTTPClient(client) 102 | return o 103 | } 104 | 105 | // SetHTTPClient adds the HTTPClient to the update one params 106 | func (o *UpdateOneParams) SetHTTPClient(client *http.Client) { 107 | o.HTTPClient = client 108 | } 109 | 110 | // WithBody adds the body to the update one params 111 | func (o *UpdateOneParams) WithBody(body *models.Item) *UpdateOneParams { 112 | o.SetBody(body) 113 | return o 114 | } 115 | 116 | // SetBody adds the body to the update one params 117 | func (o *UpdateOneParams) SetBody(body *models.Item) { 118 | o.Body = body 119 | } 120 | 121 | // WithID adds the id to the update one params 122 | func (o *UpdateOneParams) WithID(id int64) *UpdateOneParams { 123 | o.SetID(id) 124 | return o 125 | } 126 | 127 | // SetID adds the id to the update one params 128 | func (o *UpdateOneParams) SetID(id int64) { 129 | o.ID = id 130 | } 131 | 132 | // WriteToRequest writes these params to a swagger request 133 | func (o *UpdateOneParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { 134 | 135 | if err := r.SetTimeout(o.timeout); err != nil { 136 | return err 137 | } 138 | var res []error 139 | 140 | if o.Body != nil { 141 | if err := r.SetBodyParam(o.Body); err != nil { 142 | return err 143 | } 144 | } 145 | 146 | // path param id 147 | if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil { 148 | return err 149 | } 150 | 151 | if len(res) > 0 { 152 | return errors.CompositeValidationError(res...) 153 | } 154 | return nil 155 | } 156 | -------------------------------------------------------------------------------- /client/todos/update_one_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | 12 | "github.com/go-openapi/runtime" 13 | 14 | strfmt "github.com/go-openapi/strfmt" 15 | 16 | models "github.com/spkane/todo-for-terraform/models" 17 | ) 18 | 19 | // UpdateOneReader is a Reader for the UpdateOne structure. 20 | type UpdateOneReader struct { 21 | formats strfmt.Registry 22 | } 23 | 24 | // ReadResponse reads a server response into the received o. 25 | func (o *UpdateOneReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { 26 | switch response.Code() { 27 | case 200: 28 | result := NewUpdateOneOK() 29 | if err := result.readResponse(response, consumer, o.formats); err != nil { 30 | return nil, err 31 | } 32 | return result, nil 33 | default: 34 | result := NewUpdateOneDefault(response.Code()) 35 | if err := result.readResponse(response, consumer, o.formats); err != nil { 36 | return nil, err 37 | } 38 | if response.Code()/100 == 2 { 39 | return result, nil 40 | } 41 | return nil, result 42 | } 43 | } 44 | 45 | // NewUpdateOneOK creates a UpdateOneOK with default headers values 46 | func NewUpdateOneOK() *UpdateOneOK { 47 | return &UpdateOneOK{} 48 | } 49 | 50 | /*UpdateOneOK handles this case with default header values. 51 | 52 | OK 53 | */ 54 | type UpdateOneOK struct { 55 | Payload *models.Item 56 | } 57 | 58 | func (o *UpdateOneOK) Error() string { 59 | return fmt.Sprintf("[PUT /{id}][%d] updateOneOK %+v", 200, o.Payload) 60 | } 61 | 62 | func (o *UpdateOneOK) GetPayload() *models.Item { 63 | return o.Payload 64 | } 65 | 66 | func (o *UpdateOneOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 67 | 68 | o.Payload = new(models.Item) 69 | 70 | // response payload 71 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { 72 | return err 73 | } 74 | 75 | return nil 76 | } 77 | 78 | // NewUpdateOneDefault creates a UpdateOneDefault with default headers values 79 | func NewUpdateOneDefault(code int) *UpdateOneDefault { 80 | return &UpdateOneDefault{ 81 | _statusCode: code, 82 | } 83 | } 84 | 85 | /*UpdateOneDefault handles this case with default header values. 86 | 87 | error 88 | */ 89 | type UpdateOneDefault struct { 90 | _statusCode int 91 | 92 | Payload *models.Error 93 | } 94 | 95 | // Code gets the status code for the update one default response 96 | func (o *UpdateOneDefault) Code() int { 97 | return o._statusCode 98 | } 99 | 100 | func (o *UpdateOneDefault) Error() string { 101 | return fmt.Sprintf("[PUT /{id}][%d] updateOne default %+v", o._statusCode, o.Payload) 102 | } 103 | 104 | func (o *UpdateOneDefault) GetPayload() *models.Error { 105 | return o.Payload 106 | } 107 | 108 | func (o *UpdateOneDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { 109 | 110 | o.Payload = new(models.Error) 111 | 112 | // response payload 113 | if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { 114 | return err 115 | } 116 | 117 | return nil 118 | } 119 | -------------------------------------------------------------------------------- /cmd/todo-list-server/main.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | "os" 8 | 9 | loads "github.com/go-openapi/loads" 10 | flags "github.com/jessevdk/go-flags" 11 | "github.com/spkane/todo-for-terraform/restapi" 12 | "github.com/spkane/todo-for-terraform/restapi/operations" 13 | ) 14 | 15 | // This file was generated by the swagger tool. 16 | // Make sure not to overwrite this file after you generated it because all your edits would be lost! 17 | 18 | func main() { 19 | 20 | swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON) 21 | if err != nil { 22 | log.Fatalln(err) 23 | } 24 | 25 | api := operations.NewTodoListAPI(swaggerSpec) 26 | server := restapi.NewServer(api) 27 | defer server.Shutdown() 28 | 29 | parser := flags.NewParser(server, flags.Default) 30 | parser.ShortDescription = "A To Do list application" 31 | parser.LongDescription = "The product of a tutorial on goswagger.io" 32 | 33 | server.ConfigureFlags() 34 | for _, optsGroup := range api.CommandLineOptionsGroups { 35 | _, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options) 36 | if err != nil { 37 | log.Fatalln(err) 38 | } 39 | } 40 | 41 | if _, err := parser.Parse(); err != nil { 42 | code := 1 43 | if fe, ok := err.(*flags.Error); ok { 44 | if fe.Type == flags.ErrHelp { 45 | code = 0 46 | } 47 | } 48 | os.Exit(code) 49 | } 50 | 51 | server.ConfigureAPI() 52 | 53 | if err := server.Serve(); err != nil { 54 | log.Fatalln(err) 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | todo: 3 | container_name: todo 4 | build: 5 | context: . 6 | image: spkane/todo-list-server:latest 7 | restart: unless-stopped 8 | networks: 9 | - my-net 10 | ports: 11 | - "8080:80" 12 | healthcheck: 13 | test: ["CMD", "curl", "-f", "http://127.0.0.1/?limit=1"] 14 | interval: 15s 15 | timeout: 3s 16 | retries: 3 17 | networks: 18 | my-net: 19 | driver: bridge 20 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/spkane/todo-for-terraform 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/docker/go-units v0.5.0 // indirect 7 | github.com/go-openapi/errors v0.20.3 8 | github.com/go-openapi/loads v0.21.2 9 | github.com/go-openapi/runtime v0.24.1 10 | github.com/go-openapi/spec v0.20.7 11 | github.com/go-openapi/strfmt v0.21.3 12 | github.com/go-openapi/swag v0.22.3 13 | github.com/go-openapi/validate v0.22.0 14 | github.com/google/go-cmp v0.5.9 // indirect 15 | github.com/google/uuid v1.3.0 // indirect 16 | github.com/jessevdk/go-flags v1.5.0 17 | github.com/mitchellh/mapstructure v1.5.0 // indirect 18 | go.mongodb.org/mongo-driver v1.10.2 // indirect 19 | golang.org/x/net v0.23.0 20 | ) 21 | -------------------------------------------------------------------------------- /models/error.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package models 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | strfmt "github.com/go-openapi/strfmt" 10 | 11 | "github.com/go-openapi/errors" 12 | "github.com/go-openapi/swag" 13 | "github.com/go-openapi/validate" 14 | ) 15 | 16 | // Error error 17 | // swagger:model error 18 | type Error struct { 19 | 20 | // code 21 | Code int64 `json:"code,omitempty"` 22 | 23 | // message 24 | // Required: true 25 | Message *string `json:"message"` 26 | } 27 | 28 | // Validate validates this error 29 | func (m *Error) Validate(formats strfmt.Registry) error { 30 | var res []error 31 | 32 | if err := m.validateMessage(formats); err != nil { 33 | res = append(res, err) 34 | } 35 | 36 | if len(res) > 0 { 37 | return errors.CompositeValidationError(res...) 38 | } 39 | return nil 40 | } 41 | 42 | func (m *Error) validateMessage(formats strfmt.Registry) error { 43 | 44 | if err := validate.Required("message", "body", m.Message); err != nil { 45 | return err 46 | } 47 | 48 | return nil 49 | } 50 | 51 | // MarshalBinary interface implementation 52 | func (m *Error) MarshalBinary() ([]byte, error) { 53 | if m == nil { 54 | return nil, nil 55 | } 56 | return swag.WriteJSON(m) 57 | } 58 | 59 | // UnmarshalBinary interface implementation 60 | func (m *Error) UnmarshalBinary(b []byte) error { 61 | var res Error 62 | if err := swag.ReadJSON(b, &res); err != nil { 63 | return err 64 | } 65 | *m = res 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /models/find_todos_okbody.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package models 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "strconv" 10 | 11 | strfmt "github.com/go-openapi/strfmt" 12 | 13 | "github.com/go-openapi/errors" 14 | "github.com/go-openapi/swag" 15 | ) 16 | 17 | // FindTodosOKBody find todos o k body 18 | // swagger:model findTodosOKBody 19 | type FindTodosOKBody []*Item 20 | 21 | // Validate validates this find todos o k body 22 | func (m FindTodosOKBody) Validate(formats strfmt.Registry) error { 23 | var res []error 24 | 25 | for i := 0; i < len(m); i++ { 26 | 27 | if swag.IsZero(m[i]) { // not required 28 | continue 29 | } 30 | 31 | if m[i] != nil { 32 | 33 | if err := m[i].Validate(formats); err != nil { 34 | if ve, ok := err.(*errors.Validation); ok { 35 | return ve.ValidateName(strconv.Itoa(i)) 36 | } 37 | return err 38 | } 39 | } 40 | 41 | } 42 | 43 | if len(res) > 0 { 44 | return errors.CompositeValidationError(res...) 45 | } 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /models/item.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package models 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | strfmt "github.com/go-openapi/strfmt" 10 | 11 | "github.com/go-openapi/errors" 12 | "github.com/go-openapi/swag" 13 | "github.com/go-openapi/validate" 14 | ) 15 | 16 | // Item item 17 | // swagger:model item 18 | type Item struct { 19 | 20 | // completed 21 | // Required: true 22 | Completed *bool `json:"completed"` 23 | 24 | // description 25 | // Required: true 26 | // Min Length: 1 27 | Description *string `json:"description"` 28 | 29 | // id 30 | // Read Only: true 31 | ID int64 `json:"id,omitempty"` 32 | } 33 | 34 | // Validate validates this item 35 | func (m *Item) Validate(formats strfmt.Registry) error { 36 | var res []error 37 | 38 | if err := m.validateCompleted(formats); err != nil { 39 | res = append(res, err) 40 | } 41 | 42 | if err := m.validateDescription(formats); err != nil { 43 | res = append(res, err) 44 | } 45 | 46 | if len(res) > 0 { 47 | return errors.CompositeValidationError(res...) 48 | } 49 | return nil 50 | } 51 | 52 | func (m *Item) validateCompleted(formats strfmt.Registry) error { 53 | 54 | if err := validate.Required("completed", "body", m.Completed); err != nil { 55 | return err 56 | } 57 | 58 | return nil 59 | } 60 | 61 | func (m *Item) validateDescription(formats strfmt.Registry) error { 62 | 63 | if err := validate.Required("description", "body", m.Description); err != nil { 64 | return err 65 | } 66 | 67 | if err := validate.MinLength("description", "body", string(*m.Description), 1); err != nil { 68 | return err 69 | } 70 | 71 | return nil 72 | } 73 | 74 | // MarshalBinary interface implementation 75 | func (m *Item) MarshalBinary() ([]byte, error) { 76 | if m == nil { 77 | return nil, nil 78 | } 79 | return swag.WriteJSON(m) 80 | } 81 | 82 | // UnmarshalBinary interface implementation 83 | func (m *Item) UnmarshalBinary(b []byte) error { 84 | var res Item 85 | if err := swag.ReadJSON(b, &res); err != nil { 86 | return err 87 | } 88 | *m = res 89 | return nil 90 | } 91 | -------------------------------------------------------------------------------- /restapi/configure_todo_list.go: -------------------------------------------------------------------------------- 1 | package restapi 2 | 3 | import ( 4 | "crypto/tls" 5 | "fmt" 6 | "net/http" 7 | "sync" 8 | "sync/atomic" 9 | 10 | errors "github.com/go-openapi/errors" 11 | runtime "github.com/go-openapi/runtime" 12 | middleware "github.com/go-openapi/runtime/middleware" 13 | "github.com/go-openapi/swag" 14 | 15 | "github.com/spkane/todo-for-terraform/models" 16 | "github.com/spkane/todo-for-terraform/restapi/operations" 17 | "github.com/spkane/todo-for-terraform/restapi/operations/todos" 18 | ) 19 | 20 | // This file is safe to edit. Once it exists it will not be overwritten 21 | 22 | var exampleFlags = struct { 23 | Example1 string `long:"example1" description:"Sample for showing how to configure cmd-line flags"` 24 | Example2 string `long:"example2" description:"Further info at https://github.com/jessevdk/go-flags"` 25 | }{} 26 | 27 | // configureFlags is for setting up the command line flags. 28 | // This currently unused. 29 | func configureFlags(api *operations.TodoListAPI) { 30 | api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{ 31 | swag.CommandLineOptionsGroup{ 32 | ShortDescription: "Example Flags", 33 | LongDescription: "", 34 | Options: &exampleFlags, 35 | }, 36 | } 37 | } 38 | 39 | var items = make(map[int64]*models.Item) 40 | var lastID int64 41 | 42 | var itemsLock = &sync.Mutex{} 43 | 44 | // newItemID atomically generates the next item ID. 45 | func newItemID() int64 { 46 | return atomic.AddInt64(&lastID, 1) 47 | } 48 | 49 | // addItem adds a single todo 50 | func addItem(item *models.Item) error { 51 | if item == nil { 52 | return errors.New(500, "item must be present") 53 | } 54 | 55 | itemsLock.Lock() 56 | defer itemsLock.Unlock() 57 | 58 | newID := newItemID() 59 | item.ID = newID 60 | items[newID] = item 61 | 62 | return nil 63 | } 64 | 65 | // updateItem updates a single todo 66 | func updateItem(id int64, item *models.Item) error { 67 | if item == nil { 68 | return errors.New(500, "item must be present") 69 | } 70 | 71 | itemsLock.Lock() 72 | defer itemsLock.Unlock() 73 | 74 | _, exists := items[id] 75 | if !exists { 76 | return errors.NotFound("not found: item %d", id) 77 | } 78 | 79 | item.ID = id 80 | items[id] = item 81 | return nil 82 | } 83 | 84 | // deteItem deletes a single todo 85 | func deleteItem(id int64) error { 86 | itemsLock.Lock() 87 | defer itemsLock.Unlock() 88 | 89 | _, exists := items[id] 90 | if !exists { 91 | return errors.NotFound("not found: item %d", id) 92 | } 93 | 94 | delete(items, id) 95 | return nil 96 | } 97 | 98 | // getItem returns a single todo 99 | func getItem(id int64) (result []*models.Item, err error) { 100 | _, exists := items[id] 101 | if !exists { 102 | return nil, errors.NotFound("not found: item %d", id) 103 | } 104 | 105 | todo := make([]*models.Item, 0) 106 | return append(todo, items[id]), nil 107 | } 108 | 109 | // allItems returns a group of todos with some basic filtering (since & limit) 110 | func allItems(since int64, limit int32) (result []*models.Item) { 111 | result = make([]*models.Item, 0) 112 | for id, item := range items { 113 | if len(result) >= int(limit) { 114 | return 115 | } 116 | if since == 0 || id > since { 117 | result = append(result, item) 118 | } 119 | } 120 | return 121 | } 122 | 123 | // configureAPI sets up the behavior for the various API endpoints 124 | func configureAPI(api *operations.TodoListAPI) http.Handler { 125 | // configure the api here 126 | api.ServeError = errors.ServeError 127 | 128 | // Set your custom logger if needed. Default one is log.Printf 129 | // Expected interface func(string, ...interface{}) 130 | // 131 | // Example: 132 | // api.Logger = log.Printf 133 | 134 | api.JSONConsumer = runtime.JSONConsumer() 135 | 136 | api.JSONProducer = runtime.JSONProducer() 137 | 138 | api.TodosAddOneHandler = todos.AddOneHandlerFunc(func(params todos.AddOneParams) middleware.Responder { 139 | if err := addItem(params.Body); err != nil { 140 | return todos.NewAddOneDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) 141 | } 142 | return todos.NewAddOneCreated().WithPayload(params.Body) 143 | }) 144 | api.TodosDestroyOneHandler = todos.DestroyOneHandlerFunc(func(params todos.DestroyOneParams) middleware.Responder { 145 | if err := deleteItem(params.ID); err != nil { 146 | return todos.NewDestroyOneDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) 147 | } 148 | return todos.NewDestroyOneNoContent() 149 | }) 150 | api.TodosFindTodosHandler = todos.FindTodosHandlerFunc(func(params todos.FindTodosParams) middleware.Responder { 151 | mergedParams := todos.NewFindTodosParams() 152 | mergedParams.Since = swag.Int64(0) 153 | if params.Since != nil { 154 | mergedParams.Since = params.Since 155 | } 156 | if params.Limit != nil { 157 | mergedParams.Limit = params.Limit 158 | } 159 | return todos.NewFindTodosOK().WithPayload(allItems(*mergedParams.Since, *mergedParams.Limit)) 160 | }) 161 | api.TodosFindTodoHandler = todos.FindTodoHandlerFunc(func(params todos.FindTodoParams) middleware.Responder { 162 | results, err := getItem(params.ID) 163 | if err != nil { 164 | return todos.NewFindTodoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) 165 | } 166 | return todos.NewFindTodoOK().WithPayload(results) 167 | }) 168 | api.TodosUpdateOneHandler = todos.UpdateOneHandlerFunc(func(params todos.UpdateOneParams) middleware.Responder { 169 | if err := updateItem(params.ID, params.Body); err != nil { 170 | return todos.NewUpdateOneDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) 171 | } 172 | return todos.NewUpdateOneOK().WithPayload(params.Body) 173 | }) 174 | 175 | api.ServerShutdown = func() {} 176 | println(exampleFlags.Example1) 177 | println(exampleFlags.Example2) 178 | 179 | return setupGlobalMiddleware(api.Serve(setupMiddlewares)) 180 | } 181 | 182 | // configureTLS : The TLS configuration before HTTPS server starts. 183 | func configureTLS(tlsConfig *tls.Config) { 184 | // Make all necessary changes to the TLS configuration here. 185 | } 186 | 187 | // configureServer : As soon as server is initialized but not run yet, this function will be called. 188 | // If you need to modify a config, store server instance to stop it individually later, this is the place. 189 | // This function can be called multiple times, depending on the number of serving schemes. 190 | // scheme value will be set accordingly: "http", "https" or "unix" 191 | func configureServer(s *http.Server, scheme, addr string) { 192 | if exampleFlags.Example1 != "something" { 193 | fmt.Println("Starting...") 194 | } 195 | } 196 | 197 | // setupMiddlewares : The middleware configuration is for the handler executors. These do not apply to the swagger.json document. 198 | // The middleware executes after routing but before authentication, binding and validation 199 | func setupMiddlewares(handler http.Handler) http.Handler { 200 | return handler 201 | } 202 | 203 | // setupGlobalMiddleware : The middleware configuration happens before anything, this middleware also applies to serving the swagger.json document. 204 | // So this is a good place to plug in a panic handling middleware, logging and metrics 205 | func setupGlobalMiddleware(handler http.Handler) http.Handler { 206 | return handler 207 | } 208 | -------------------------------------------------------------------------------- /restapi/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | /* 4 | Package restapi A To Do list application 5 | The product of a tutorial on goswagger.io 6 | 7 | 8 | Schemes: 9 | http 10 | Host: localhost 11 | BasePath: / 12 | Version: 1.0.0 13 | 14 | Consumes: 15 | - application/spkane.todo-list.v1+json 16 | 17 | Produces: 18 | - application/spkane.todo-list.v1+json 19 | 20 | swagger:meta 21 | */ 22 | package restapi 23 | -------------------------------------------------------------------------------- /restapi/embedded_spec.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package restapi 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "encoding/json" 10 | ) 11 | 12 | var ( 13 | // SwaggerJSON embedded version of the swagger document used at generation time 14 | SwaggerJSON json.RawMessage 15 | // FlatSwaggerJSON embedded flattened version of the swagger document used at generation time 16 | FlatSwaggerJSON json.RawMessage 17 | ) 18 | 19 | func init() { 20 | SwaggerJSON = json.RawMessage([]byte(`{ 21 | "consumes": [ 22 | "application/spkane.todo-list.v1+json" 23 | ], 24 | "produces": [ 25 | "application/spkane.todo-list.v1+json" 26 | ], 27 | "schemes": [ 28 | "http" 29 | ], 30 | "swagger": "2.0", 31 | "info": { 32 | "description": "The product of a tutorial on goswagger.io", 33 | "title": "A To Do list application", 34 | "version": "1.0.0" 35 | }, 36 | "paths": { 37 | "/": { 38 | "get": { 39 | "tags": [ 40 | "todos" 41 | ], 42 | "operationId": "findTodos", 43 | "parameters": [ 44 | { 45 | "type": "integer", 46 | "format": "int64", 47 | "name": "since", 48 | "in": "query" 49 | }, 50 | { 51 | "type": "integer", 52 | "format": "int32", 53 | "default": 20, 54 | "name": "limit", 55 | "in": "query" 56 | } 57 | ], 58 | "responses": { 59 | "200": { 60 | "description": "list the todo operations", 61 | "schema": { 62 | "type": "array", 63 | "items": { 64 | "$ref": "#/definitions/item" 65 | } 66 | } 67 | }, 68 | "default": { 69 | "description": "generic error response", 70 | "schema": { 71 | "$ref": "#/definitions/error" 72 | } 73 | } 74 | } 75 | }, 76 | "post": { 77 | "tags": [ 78 | "todos" 79 | ], 80 | "operationId": "addOne", 81 | "parameters": [ 82 | { 83 | "name": "body", 84 | "in": "body", 85 | "schema": { 86 | "$ref": "#/definitions/item" 87 | } 88 | } 89 | ], 90 | "responses": { 91 | "201": { 92 | "description": "Created", 93 | "schema": { 94 | "$ref": "#/definitions/item" 95 | } 96 | }, 97 | "default": { 98 | "description": "error", 99 | "schema": { 100 | "$ref": "#/definitions/error" 101 | } 102 | } 103 | } 104 | } 105 | }, 106 | "/{id}": { 107 | "get": { 108 | "tags": [ 109 | "todos" 110 | ], 111 | "operationId": "findTodo", 112 | "responses": { 113 | "200": { 114 | "description": "list the todo", 115 | "schema": { 116 | "type": "array", 117 | "items": { 118 | "$ref": "#/definitions/item" 119 | } 120 | } 121 | }, 122 | "default": { 123 | "description": "generic error response", 124 | "schema": { 125 | "$ref": "#/definitions/error" 126 | } 127 | } 128 | } 129 | }, 130 | "put": { 131 | "tags": [ 132 | "todos" 133 | ], 134 | "operationId": "updateOne", 135 | "parameters": [ 136 | { 137 | "name": "body", 138 | "in": "body", 139 | "schema": { 140 | "$ref": "#/definitions/item" 141 | } 142 | } 143 | ], 144 | "responses": { 145 | "200": { 146 | "description": "OK", 147 | "schema": { 148 | "$ref": "#/definitions/item" 149 | } 150 | }, 151 | "default": { 152 | "description": "error", 153 | "schema": { 154 | "$ref": "#/definitions/error" 155 | } 156 | } 157 | } 158 | }, 159 | "delete": { 160 | "tags": [ 161 | "todos" 162 | ], 163 | "operationId": "destroyOne", 164 | "responses": { 165 | "204": { 166 | "description": "Deleted" 167 | }, 168 | "default": { 169 | "description": "error", 170 | "schema": { 171 | "$ref": "#/definitions/error" 172 | } 173 | } 174 | } 175 | }, 176 | "parameters": [ 177 | { 178 | "type": "integer", 179 | "format": "int64", 180 | "name": "id", 181 | "in": "path", 182 | "required": true 183 | } 184 | ] 185 | } 186 | }, 187 | "definitions": { 188 | "error": { 189 | "type": "object", 190 | "required": [ 191 | "message" 192 | ], 193 | "properties": { 194 | "code": { 195 | "type": "integer", 196 | "format": "int64" 197 | }, 198 | "message": { 199 | "type": "string" 200 | } 201 | } 202 | }, 203 | "item": { 204 | "type": "object", 205 | "required": [ 206 | "description", 207 | "completed" 208 | ], 209 | "properties": { 210 | "completed": { 211 | "type": "boolean" 212 | }, 213 | "description": { 214 | "type": "string", 215 | "minLength": 1 216 | }, 217 | "id": { 218 | "type": "integer", 219 | "format": "int64", 220 | "readOnly": true 221 | } 222 | } 223 | } 224 | } 225 | }`)) 226 | FlatSwaggerJSON = json.RawMessage([]byte(`{ 227 | "consumes": [ 228 | "application/spkane.todo-list.v1+json" 229 | ], 230 | "produces": [ 231 | "application/spkane.todo-list.v1+json" 232 | ], 233 | "schemes": [ 234 | "http" 235 | ], 236 | "swagger": "2.0", 237 | "info": { 238 | "description": "The product of a tutorial on goswagger.io", 239 | "title": "A To Do list application", 240 | "version": "1.0.0" 241 | }, 242 | "paths": { 243 | "/": { 244 | "get": { 245 | "tags": [ 246 | "todos" 247 | ], 248 | "operationId": "findTodos", 249 | "parameters": [ 250 | { 251 | "type": "integer", 252 | "format": "int64", 253 | "name": "since", 254 | "in": "query" 255 | }, 256 | { 257 | "type": "integer", 258 | "format": "int32", 259 | "default": 20, 260 | "name": "limit", 261 | "in": "query" 262 | } 263 | ], 264 | "responses": { 265 | "200": { 266 | "description": "list the todo operations", 267 | "schema": { 268 | "type": "array", 269 | "items": { 270 | "$ref": "#/definitions/item" 271 | } 272 | } 273 | }, 274 | "default": { 275 | "description": "generic error response", 276 | "schema": { 277 | "$ref": "#/definitions/error" 278 | } 279 | } 280 | } 281 | }, 282 | "post": { 283 | "tags": [ 284 | "todos" 285 | ], 286 | "operationId": "addOne", 287 | "parameters": [ 288 | { 289 | "name": "body", 290 | "in": "body", 291 | "schema": { 292 | "$ref": "#/definitions/item" 293 | } 294 | } 295 | ], 296 | "responses": { 297 | "201": { 298 | "description": "Created", 299 | "schema": { 300 | "$ref": "#/definitions/item" 301 | } 302 | }, 303 | "default": { 304 | "description": "error", 305 | "schema": { 306 | "$ref": "#/definitions/error" 307 | } 308 | } 309 | } 310 | } 311 | }, 312 | "/{id}": { 313 | "get": { 314 | "tags": [ 315 | "todos" 316 | ], 317 | "operationId": "findTodo", 318 | "responses": { 319 | "200": { 320 | "description": "list the todo", 321 | "schema": { 322 | "type": "array", 323 | "items": { 324 | "$ref": "#/definitions/item" 325 | } 326 | } 327 | }, 328 | "default": { 329 | "description": "generic error response", 330 | "schema": { 331 | "$ref": "#/definitions/error" 332 | } 333 | } 334 | } 335 | }, 336 | "put": { 337 | "tags": [ 338 | "todos" 339 | ], 340 | "operationId": "updateOne", 341 | "parameters": [ 342 | { 343 | "name": "body", 344 | "in": "body", 345 | "schema": { 346 | "$ref": "#/definitions/item" 347 | } 348 | } 349 | ], 350 | "responses": { 351 | "200": { 352 | "description": "OK", 353 | "schema": { 354 | "$ref": "#/definitions/item" 355 | } 356 | }, 357 | "default": { 358 | "description": "error", 359 | "schema": { 360 | "$ref": "#/definitions/error" 361 | } 362 | } 363 | } 364 | }, 365 | "delete": { 366 | "tags": [ 367 | "todos" 368 | ], 369 | "operationId": "destroyOne", 370 | "responses": { 371 | "204": { 372 | "description": "Deleted" 373 | }, 374 | "default": { 375 | "description": "error", 376 | "schema": { 377 | "$ref": "#/definitions/error" 378 | } 379 | } 380 | } 381 | }, 382 | "parameters": [ 383 | { 384 | "type": "integer", 385 | "format": "int64", 386 | "name": "id", 387 | "in": "path", 388 | "required": true 389 | } 390 | ] 391 | } 392 | }, 393 | "definitions": { 394 | "error": { 395 | "type": "object", 396 | "required": [ 397 | "message" 398 | ], 399 | "properties": { 400 | "code": { 401 | "type": "integer", 402 | "format": "int64" 403 | }, 404 | "message": { 405 | "type": "string" 406 | } 407 | } 408 | }, 409 | "item": { 410 | "type": "object", 411 | "required": [ 412 | "description", 413 | "completed" 414 | ], 415 | "properties": { 416 | "completed": { 417 | "type": "boolean" 418 | }, 419 | "description": { 420 | "type": "string", 421 | "minLength": 1 422 | }, 423 | "id": { 424 | "type": "integer", 425 | "format": "int64", 426 | "readOnly": true 427 | } 428 | } 429 | } 430 | } 431 | }`)) 432 | } 433 | -------------------------------------------------------------------------------- /restapi/operations/todo_list_api.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package operations 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "fmt" 10 | "net/http" 11 | "strings" 12 | 13 | errors "github.com/go-openapi/errors" 14 | loads "github.com/go-openapi/loads" 15 | runtime "github.com/go-openapi/runtime" 16 | middleware "github.com/go-openapi/runtime/middleware" 17 | security "github.com/go-openapi/runtime/security" 18 | spec "github.com/go-openapi/spec" 19 | strfmt "github.com/go-openapi/strfmt" 20 | "github.com/go-openapi/swag" 21 | 22 | "github.com/spkane/todo-for-terraform/restapi/operations/todos" 23 | ) 24 | 25 | // NewTodoListAPI creates a new TodoList instance 26 | func NewTodoListAPI(spec *loads.Document) *TodoListAPI { 27 | return &TodoListAPI{ 28 | handlers: make(map[string]map[string]http.Handler), 29 | formats: strfmt.Default, 30 | defaultConsumes: "application/json", 31 | defaultProduces: "application/json", 32 | customConsumers: make(map[string]runtime.Consumer), 33 | customProducers: make(map[string]runtime.Producer), 34 | ServerShutdown: func() {}, 35 | spec: spec, 36 | ServeError: errors.ServeError, 37 | BasicAuthenticator: security.BasicAuth, 38 | APIKeyAuthenticator: security.APIKeyAuth, 39 | BearerAuthenticator: security.BearerAuth, 40 | JSONConsumer: runtime.JSONConsumer(), 41 | JSONProducer: runtime.JSONProducer(), 42 | TodosAddOneHandler: todos.AddOneHandlerFunc(func(params todos.AddOneParams) middleware.Responder { 43 | return middleware.NotImplemented("operation TodosAddOne has not yet been implemented") 44 | }), 45 | TodosDestroyOneHandler: todos.DestroyOneHandlerFunc(func(params todos.DestroyOneParams) middleware.Responder { 46 | return middleware.NotImplemented("operation TodosDestroyOne has not yet been implemented") 47 | }), 48 | TodosFindTodoHandler: todos.FindTodoHandlerFunc(func(params todos.FindTodoParams) middleware.Responder { 49 | return middleware.NotImplemented("operation TodosFindTodo has not yet been implemented") 50 | }), 51 | TodosFindTodosHandler: todos.FindTodosHandlerFunc(func(params todos.FindTodosParams) middleware.Responder { 52 | return middleware.NotImplemented("operation TodosFindTodos has not yet been implemented") 53 | }), 54 | TodosUpdateOneHandler: todos.UpdateOneHandlerFunc(func(params todos.UpdateOneParams) middleware.Responder { 55 | return middleware.NotImplemented("operation TodosUpdateOne has not yet been implemented") 56 | }), 57 | } 58 | } 59 | 60 | /*TodoListAPI The product of a tutorial on goswagger.io */ 61 | type TodoListAPI struct { 62 | spec *loads.Document 63 | context *middleware.Context 64 | handlers map[string]map[string]http.Handler 65 | formats strfmt.Registry 66 | customConsumers map[string]runtime.Consumer 67 | customProducers map[string]runtime.Producer 68 | defaultConsumes string 69 | defaultProduces string 70 | Middleware func(middleware.Builder) http.Handler 71 | 72 | // BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function. 73 | // It has a default implementation in the security package, however you can replace it for your particular usage. 74 | BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator 75 | // APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function. 76 | // It has a default implementation in the security package, however you can replace it for your particular usage. 77 | APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator 78 | // BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function. 79 | // It has a default implementation in the security package, however you can replace it for your particular usage. 80 | BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator 81 | 82 | // JSONConsumer registers a consumer for a "application/spkane.todo-list.v1+json" mime type 83 | JSONConsumer runtime.Consumer 84 | 85 | // JSONProducer registers a producer for a "application/spkane.todo-list.v1+json" mime type 86 | JSONProducer runtime.Producer 87 | 88 | // TodosAddOneHandler sets the operation handler for the add one operation 89 | TodosAddOneHandler todos.AddOneHandler 90 | // TodosDestroyOneHandler sets the operation handler for the destroy one operation 91 | TodosDestroyOneHandler todos.DestroyOneHandler 92 | // TodosFindTodoHandler sets the operation handler for the find todo operation 93 | TodosFindTodoHandler todos.FindTodoHandler 94 | // TodosFindTodosHandler sets the operation handler for the find todos operation 95 | TodosFindTodosHandler todos.FindTodosHandler 96 | // TodosUpdateOneHandler sets the operation handler for the update one operation 97 | TodosUpdateOneHandler todos.UpdateOneHandler 98 | 99 | // ServeError is called when an error is received, there is a default handler 100 | // but you can set your own with this 101 | ServeError func(http.ResponseWriter, *http.Request, error) 102 | 103 | // ServerShutdown is called when the HTTP(S) server is shut down and done 104 | // handling all active connections and does not accept connections any more 105 | ServerShutdown func() 106 | 107 | // Custom command line argument groups with their descriptions 108 | CommandLineOptionsGroups []swag.CommandLineOptionsGroup 109 | 110 | // User defined logger function. 111 | Logger func(string, ...interface{}) 112 | } 113 | 114 | // SetDefaultProduces sets the default produces media type 115 | func (o *TodoListAPI) SetDefaultProduces(mediaType string) { 116 | o.defaultProduces = mediaType 117 | } 118 | 119 | // SetDefaultConsumes returns the default consumes media type 120 | func (o *TodoListAPI) SetDefaultConsumes(mediaType string) { 121 | o.defaultConsumes = mediaType 122 | } 123 | 124 | // SetSpec sets a spec that will be served for the clients. 125 | func (o *TodoListAPI) SetSpec(spec *loads.Document) { 126 | o.spec = spec 127 | } 128 | 129 | // DefaultProduces returns the default produces media type 130 | func (o *TodoListAPI) DefaultProduces() string { 131 | return o.defaultProduces 132 | } 133 | 134 | // DefaultConsumes returns the default consumes media type 135 | func (o *TodoListAPI) DefaultConsumes() string { 136 | return o.defaultConsumes 137 | } 138 | 139 | // Formats returns the registered string formats 140 | func (o *TodoListAPI) Formats() strfmt.Registry { 141 | return o.formats 142 | } 143 | 144 | // RegisterFormat registers a custom format validator 145 | func (o *TodoListAPI) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) { 146 | o.formats.Add(name, format, validator) 147 | } 148 | 149 | // Validate validates the registrations in the TodoListAPI 150 | func (o *TodoListAPI) Validate() error { 151 | var unregistered []string 152 | 153 | if o.JSONConsumer == nil { 154 | unregistered = append(unregistered, "JSONConsumer") 155 | } 156 | 157 | if o.JSONProducer == nil { 158 | unregistered = append(unregistered, "JSONProducer") 159 | } 160 | 161 | if o.TodosAddOneHandler == nil { 162 | unregistered = append(unregistered, "todos.AddOneHandler") 163 | } 164 | 165 | if o.TodosDestroyOneHandler == nil { 166 | unregistered = append(unregistered, "todos.DestroyOneHandler") 167 | } 168 | 169 | if o.TodosFindTodoHandler == nil { 170 | unregistered = append(unregistered, "todos.FindTodoHandler") 171 | } 172 | 173 | if o.TodosFindTodosHandler == nil { 174 | unregistered = append(unregistered, "todos.FindTodosHandler") 175 | } 176 | 177 | if o.TodosUpdateOneHandler == nil { 178 | unregistered = append(unregistered, "todos.UpdateOneHandler") 179 | } 180 | 181 | if len(unregistered) > 0 { 182 | return fmt.Errorf("missing registration: %s", strings.Join(unregistered, ", ")) 183 | } 184 | 185 | return nil 186 | } 187 | 188 | // ServeErrorFor gets a error handler for a given operation id 189 | func (o *TodoListAPI) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) { 190 | return o.ServeError 191 | } 192 | 193 | // AuthenticatorsFor gets the authenticators for the specified security schemes 194 | func (o *TodoListAPI) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { 195 | 196 | return nil 197 | 198 | } 199 | 200 | // Authorizer returns the registered authorizer 201 | func (o *TodoListAPI) Authorizer() runtime.Authorizer { 202 | 203 | return nil 204 | 205 | } 206 | 207 | // ConsumersFor gets the consumers for the specified media types 208 | func (o *TodoListAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { 209 | 210 | result := make(map[string]runtime.Consumer) 211 | for _, mt := range mediaTypes { 212 | switch mt { 213 | 214 | case "application/spkane.todo-list.v1+json": 215 | result["application/spkane.todo-list.v1+json"] = o.JSONConsumer 216 | 217 | } 218 | 219 | if c, ok := o.customConsumers[mt]; ok { 220 | result[mt] = c 221 | } 222 | } 223 | return result 224 | 225 | } 226 | 227 | // ProducersFor gets the producers for the specified media types 228 | func (o *TodoListAPI) ProducersFor(mediaTypes []string) map[string]runtime.Producer { 229 | 230 | result := make(map[string]runtime.Producer) 231 | for _, mt := range mediaTypes { 232 | switch mt { 233 | 234 | case "application/spkane.todo-list.v1+json": 235 | result["application/spkane.todo-list.v1+json"] = o.JSONProducer 236 | 237 | } 238 | 239 | if p, ok := o.customProducers[mt]; ok { 240 | result[mt] = p 241 | } 242 | } 243 | return result 244 | 245 | } 246 | 247 | // HandlerFor gets a http.Handler for the provided operation method and path 248 | func (o *TodoListAPI) HandlerFor(method, path string) (http.Handler, bool) { 249 | if o.handlers == nil { 250 | return nil, false 251 | } 252 | um := strings.ToUpper(method) 253 | if _, ok := o.handlers[um]; !ok { 254 | return nil, false 255 | } 256 | if path == "/" { 257 | path = "" 258 | } 259 | h, ok := o.handlers[um][path] 260 | return h, ok 261 | } 262 | 263 | // Context returns the middleware context for the todo list API 264 | func (o *TodoListAPI) Context() *middleware.Context { 265 | if o.context == nil { 266 | o.context = middleware.NewRoutableContext(o.spec, o, nil) 267 | } 268 | 269 | return o.context 270 | } 271 | 272 | func (o *TodoListAPI) initHandlerCache() { 273 | o.Context() // don't care about the result, just that the initialization happened 274 | 275 | if o.handlers == nil { 276 | o.handlers = make(map[string]map[string]http.Handler) 277 | } 278 | 279 | if o.handlers["POST"] == nil { 280 | o.handlers["POST"] = make(map[string]http.Handler) 281 | } 282 | o.handlers["POST"][""] = todos.NewAddOne(o.context, o.TodosAddOneHandler) 283 | 284 | if o.handlers["DELETE"] == nil { 285 | o.handlers["DELETE"] = make(map[string]http.Handler) 286 | } 287 | o.handlers["DELETE"]["/{id}"] = todos.NewDestroyOne(o.context, o.TodosDestroyOneHandler) 288 | 289 | if o.handlers["GET"] == nil { 290 | o.handlers["GET"] = make(map[string]http.Handler) 291 | } 292 | o.handlers["GET"]["/{id}"] = todos.NewFindTodo(o.context, o.TodosFindTodoHandler) 293 | 294 | if o.handlers["GET"] == nil { 295 | o.handlers["GET"] = make(map[string]http.Handler) 296 | } 297 | o.handlers["GET"][""] = todos.NewFindTodos(o.context, o.TodosFindTodosHandler) 298 | 299 | if o.handlers["PUT"] == nil { 300 | o.handlers["PUT"] = make(map[string]http.Handler) 301 | } 302 | o.handlers["PUT"]["/{id}"] = todos.NewUpdateOne(o.context, o.TodosUpdateOneHandler) 303 | 304 | } 305 | 306 | // Serve creates a http handler to serve the API over HTTP 307 | // can be used directly in http.ListenAndServe(":8000", api.Serve(nil)) 308 | func (o *TodoListAPI) Serve(builder middleware.Builder) http.Handler { 309 | o.Init() 310 | 311 | if o.Middleware != nil { 312 | return o.Middleware(builder) 313 | } 314 | return o.context.APIHandler(builder) 315 | } 316 | 317 | // Init allows you to just initialize the handler cache, you can then recompose the middleware as you see fit 318 | func (o *TodoListAPI) Init() { 319 | if len(o.handlers) == 0 { 320 | o.initHandlerCache() 321 | } 322 | } 323 | 324 | // RegisterConsumer allows you to add (or override) a consumer for a media type. 325 | func (o *TodoListAPI) RegisterConsumer(mediaType string, consumer runtime.Consumer) { 326 | o.customConsumers[mediaType] = consumer 327 | } 328 | 329 | // RegisterProducer allows you to add (or override) a producer for a media type. 330 | func (o *TodoListAPI) RegisterProducer(mediaType string, producer runtime.Producer) { 331 | o.customProducers[mediaType] = producer 332 | } 333 | -------------------------------------------------------------------------------- /restapi/operations/todos/add_one.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | middleware "github.com/go-openapi/runtime/middleware" 12 | ) 13 | 14 | // AddOneHandlerFunc turns a function with the right signature into a add one handler 15 | type AddOneHandlerFunc func(AddOneParams) middleware.Responder 16 | 17 | // Handle executing the request and returning a response 18 | func (fn AddOneHandlerFunc) Handle(params AddOneParams) middleware.Responder { 19 | return fn(params) 20 | } 21 | 22 | // AddOneHandler interface for that can handle valid add one params 23 | type AddOneHandler interface { 24 | Handle(AddOneParams) middleware.Responder 25 | } 26 | 27 | // NewAddOne creates a new http.Handler for the add one operation 28 | func NewAddOne(ctx *middleware.Context, handler AddOneHandler) *AddOne { 29 | return &AddOne{Context: ctx, Handler: handler} 30 | } 31 | 32 | /*AddOne swagger:route POST / todos addOne 33 | 34 | AddOne add one API 35 | 36 | */ 37 | type AddOne struct { 38 | Context *middleware.Context 39 | Handler AddOneHandler 40 | } 41 | 42 | func (o *AddOne) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 43 | route, rCtx, _ := o.Context.RouteInfo(r) 44 | if rCtx != nil { 45 | r = rCtx 46 | } 47 | var Params = NewAddOneParams() 48 | 49 | if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params 50 | o.Context.Respond(rw, r, route.Produces, route, err) 51 | return 52 | } 53 | 54 | res := o.Handler.Handle(Params) // actually handle the request 55 | 56 | o.Context.Respond(rw, r, route.Produces, route, res) 57 | 58 | } 59 | -------------------------------------------------------------------------------- /restapi/operations/todos/add_one_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/errors" 12 | "github.com/go-openapi/runtime" 13 | "github.com/go-openapi/runtime/middleware" 14 | 15 | models "github.com/spkane/todo-for-terraform/models" 16 | ) 17 | 18 | // NewAddOneParams creates a new AddOneParams object 19 | // no default values defined in spec. 20 | func NewAddOneParams() AddOneParams { 21 | 22 | return AddOneParams{} 23 | } 24 | 25 | // AddOneParams contains all the bound params for the add one operation 26 | // typically these are obtained from a http.Request 27 | // 28 | // swagger:parameters addOne 29 | type AddOneParams struct { 30 | 31 | // HTTP Request Object 32 | HTTPRequest *http.Request `json:"-"` 33 | 34 | /* 35 | In: body 36 | */ 37 | Body *models.Item 38 | } 39 | 40 | // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface 41 | // for simple values it will use straight method calls. 42 | // 43 | // To ensure default values, the struct must have been initialized with NewAddOneParams() beforehand. 44 | func (o *AddOneParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { 45 | var res []error 46 | 47 | o.HTTPRequest = r 48 | 49 | if runtime.HasBody(r) { 50 | defer r.Body.Close() 51 | var body models.Item 52 | if err := route.Consumer.Consume(r.Body, &body); err != nil { 53 | res = append(res, errors.NewParseError("body", "body", "", err)) 54 | } else { 55 | // validate body object 56 | if err := body.Validate(route.Formats); err != nil { 57 | res = append(res, err) 58 | } 59 | 60 | if len(res) == 0 { 61 | o.Body = &body 62 | } 63 | } 64 | } 65 | if len(res) > 0 { 66 | return errors.CompositeValidationError(res...) 67 | } 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /restapi/operations/todos/add_one_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/runtime" 12 | 13 | models "github.com/spkane/todo-for-terraform/models" 14 | ) 15 | 16 | // AddOneCreatedCode is the HTTP code returned for type AddOneCreated 17 | const AddOneCreatedCode int = 201 18 | 19 | /*AddOneCreated Created 20 | 21 | swagger:response addOneCreated 22 | */ 23 | type AddOneCreated struct { 24 | 25 | /* 26 | In: Body 27 | */ 28 | Payload *models.Item `json:"body,omitempty"` 29 | } 30 | 31 | // NewAddOneCreated creates AddOneCreated with default headers values 32 | func NewAddOneCreated() *AddOneCreated { 33 | 34 | return &AddOneCreated{} 35 | } 36 | 37 | // WithPayload adds the payload to the add one created response 38 | func (o *AddOneCreated) WithPayload(payload *models.Item) *AddOneCreated { 39 | o.Payload = payload 40 | return o 41 | } 42 | 43 | // SetPayload sets the payload to the add one created response 44 | func (o *AddOneCreated) SetPayload(payload *models.Item) { 45 | o.Payload = payload 46 | } 47 | 48 | // WriteResponse to the client 49 | func (o *AddOneCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 50 | 51 | rw.WriteHeader(201) 52 | if o.Payload != nil { 53 | payload := o.Payload 54 | if err := producer.Produce(rw, payload); err != nil { 55 | panic(err) // let the recovery middleware deal with this 56 | } 57 | } 58 | } 59 | 60 | /*AddOneDefault error 61 | 62 | swagger:response addOneDefault 63 | */ 64 | type AddOneDefault struct { 65 | _statusCode int 66 | 67 | /* 68 | In: Body 69 | */ 70 | Payload *models.Error `json:"body,omitempty"` 71 | } 72 | 73 | // NewAddOneDefault creates AddOneDefault with default headers values 74 | func NewAddOneDefault(code int) *AddOneDefault { 75 | if code <= 0 { 76 | code = 500 77 | } 78 | 79 | return &AddOneDefault{ 80 | _statusCode: code, 81 | } 82 | } 83 | 84 | // WithStatusCode adds the status to the add one default response 85 | func (o *AddOneDefault) WithStatusCode(code int) *AddOneDefault { 86 | o._statusCode = code 87 | return o 88 | } 89 | 90 | // SetStatusCode sets the status to the add one default response 91 | func (o *AddOneDefault) SetStatusCode(code int) { 92 | o._statusCode = code 93 | } 94 | 95 | // WithPayload adds the payload to the add one default response 96 | func (o *AddOneDefault) WithPayload(payload *models.Error) *AddOneDefault { 97 | o.Payload = payload 98 | return o 99 | } 100 | 101 | // SetPayload sets the payload to the add one default response 102 | func (o *AddOneDefault) SetPayload(payload *models.Error) { 103 | o.Payload = payload 104 | } 105 | 106 | // WriteResponse to the client 107 | func (o *AddOneDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 108 | 109 | rw.WriteHeader(o._statusCode) 110 | if o.Payload != nil { 111 | payload := o.Payload 112 | if err := producer.Produce(rw, payload); err != nil { 113 | panic(err) // let the recovery middleware deal with this 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /restapi/operations/todos/add_one_urlbuilder.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "errors" 10 | "net/url" 11 | golangswaggerpaths "path" 12 | ) 13 | 14 | // AddOneURL generates an URL for the add one operation 15 | type AddOneURL struct { 16 | _basePath string 17 | } 18 | 19 | // WithBasePath sets the base path for this url builder, only required when it's different from the 20 | // base path specified in the swagger spec. 21 | // When the value of the base path is an empty string 22 | func (o *AddOneURL) WithBasePath(bp string) *AddOneURL { 23 | o.SetBasePath(bp) 24 | return o 25 | } 26 | 27 | // SetBasePath sets the base path for this url builder, only required when it's different from the 28 | // base path specified in the swagger spec. 29 | // When the value of the base path is an empty string 30 | func (o *AddOneURL) SetBasePath(bp string) { 31 | o._basePath = bp 32 | } 33 | 34 | // Build a url path and query string 35 | func (o *AddOneURL) Build() (*url.URL, error) { 36 | var _result url.URL 37 | 38 | var _path = "/" 39 | 40 | _basePath := o._basePath 41 | _result.Path = golangswaggerpaths.Join(_basePath, _path) 42 | 43 | return &_result, nil 44 | } 45 | 46 | // Must is a helper function to panic when the url builder returns an error 47 | func (o *AddOneURL) Must(u *url.URL, err error) *url.URL { 48 | if err != nil { 49 | panic(err) 50 | } 51 | if u == nil { 52 | panic("url can't be nil") 53 | } 54 | return u 55 | } 56 | 57 | // String returns the string representation of the path with query string 58 | func (o *AddOneURL) String() string { 59 | return o.Must(o.Build()).String() 60 | } 61 | 62 | // BuildFull builds a full url with scheme, host, path and query string 63 | func (o *AddOneURL) BuildFull(scheme, host string) (*url.URL, error) { 64 | if scheme == "" { 65 | return nil, errors.New("scheme is required for a full url on AddOneURL") 66 | } 67 | if host == "" { 68 | return nil, errors.New("host is required for a full url on AddOneURL") 69 | } 70 | 71 | base, err := o.Build() 72 | if err != nil { 73 | return nil, err 74 | } 75 | 76 | base.Scheme = scheme 77 | base.Host = host 78 | return base, nil 79 | } 80 | 81 | // StringFull returns the string representation of a complete url 82 | func (o *AddOneURL) StringFull(scheme, host string) string { 83 | return o.Must(o.BuildFull(scheme, host)).String() 84 | } 85 | -------------------------------------------------------------------------------- /restapi/operations/todos/destroy_one.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | middleware "github.com/go-openapi/runtime/middleware" 12 | ) 13 | 14 | // DestroyOneHandlerFunc turns a function with the right signature into a destroy one handler 15 | type DestroyOneHandlerFunc func(DestroyOneParams) middleware.Responder 16 | 17 | // Handle executing the request and returning a response 18 | func (fn DestroyOneHandlerFunc) Handle(params DestroyOneParams) middleware.Responder { 19 | return fn(params) 20 | } 21 | 22 | // DestroyOneHandler interface for that can handle valid destroy one params 23 | type DestroyOneHandler interface { 24 | Handle(DestroyOneParams) middleware.Responder 25 | } 26 | 27 | // NewDestroyOne creates a new http.Handler for the destroy one operation 28 | func NewDestroyOne(ctx *middleware.Context, handler DestroyOneHandler) *DestroyOne { 29 | return &DestroyOne{Context: ctx, Handler: handler} 30 | } 31 | 32 | /*DestroyOne swagger:route DELETE /{id} todos destroyOne 33 | 34 | DestroyOne destroy one API 35 | 36 | */ 37 | type DestroyOne struct { 38 | Context *middleware.Context 39 | Handler DestroyOneHandler 40 | } 41 | 42 | func (o *DestroyOne) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 43 | route, rCtx, _ := o.Context.RouteInfo(r) 44 | if rCtx != nil { 45 | r = rCtx 46 | } 47 | var Params = NewDestroyOneParams() 48 | 49 | if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params 50 | o.Context.Respond(rw, r, route.Produces, route, err) 51 | return 52 | } 53 | 54 | res := o.Handler.Handle(Params) // actually handle the request 55 | 56 | o.Context.Respond(rw, r, route.Produces, route, res) 57 | 58 | } 59 | -------------------------------------------------------------------------------- /restapi/operations/todos/destroy_one_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/errors" 12 | "github.com/go-openapi/runtime/middleware" 13 | "github.com/go-openapi/swag" 14 | 15 | strfmt "github.com/go-openapi/strfmt" 16 | ) 17 | 18 | // NewDestroyOneParams creates a new DestroyOneParams object 19 | // no default values defined in spec. 20 | func NewDestroyOneParams() DestroyOneParams { 21 | 22 | return DestroyOneParams{} 23 | } 24 | 25 | // DestroyOneParams contains all the bound params for the destroy one operation 26 | // typically these are obtained from a http.Request 27 | // 28 | // swagger:parameters destroyOne 29 | type DestroyOneParams struct { 30 | 31 | // HTTP Request Object 32 | HTTPRequest *http.Request `json:"-"` 33 | 34 | /* 35 | Required: true 36 | In: path 37 | */ 38 | ID int64 39 | } 40 | 41 | // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface 42 | // for simple values it will use straight method calls. 43 | // 44 | // To ensure default values, the struct must have been initialized with NewDestroyOneParams() beforehand. 45 | func (o *DestroyOneParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { 46 | var res []error 47 | 48 | o.HTTPRequest = r 49 | 50 | rID, rhkID, _ := route.Params.GetOK("id") 51 | if err := o.bindID(rID, rhkID, route.Formats); err != nil { 52 | res = append(res, err) 53 | } 54 | 55 | if len(res) > 0 { 56 | return errors.CompositeValidationError(res...) 57 | } 58 | return nil 59 | } 60 | 61 | // bindID binds and validates parameter ID from path. 62 | func (o *DestroyOneParams) bindID(rawData []string, hasKey bool, formats strfmt.Registry) error { 63 | var raw string 64 | if len(rawData) > 0 { 65 | raw = rawData[len(rawData)-1] 66 | } 67 | 68 | // Required: true 69 | // Parameter is provided by construction from the route 70 | 71 | value, err := swag.ConvertInt64(raw) 72 | if err != nil { 73 | return errors.InvalidType("id", "path", "int64", raw) 74 | } 75 | o.ID = value 76 | 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /restapi/operations/todos/destroy_one_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/runtime" 12 | 13 | models "github.com/spkane/todo-for-terraform/models" 14 | ) 15 | 16 | // DestroyOneNoContentCode is the HTTP code returned for type DestroyOneNoContent 17 | const DestroyOneNoContentCode int = 204 18 | 19 | /*DestroyOneNoContent Deleted 20 | 21 | swagger:response destroyOneNoContent 22 | */ 23 | type DestroyOneNoContent struct { 24 | } 25 | 26 | // NewDestroyOneNoContent creates DestroyOneNoContent with default headers values 27 | func NewDestroyOneNoContent() *DestroyOneNoContent { 28 | 29 | return &DestroyOneNoContent{} 30 | } 31 | 32 | // WriteResponse to the client 33 | func (o *DestroyOneNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 34 | 35 | rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses 36 | 37 | rw.WriteHeader(204) 38 | } 39 | 40 | /*DestroyOneDefault error 41 | 42 | swagger:response destroyOneDefault 43 | */ 44 | type DestroyOneDefault struct { 45 | _statusCode int 46 | 47 | /* 48 | In: Body 49 | */ 50 | Payload *models.Error `json:"body,omitempty"` 51 | } 52 | 53 | // NewDestroyOneDefault creates DestroyOneDefault with default headers values 54 | func NewDestroyOneDefault(code int) *DestroyOneDefault { 55 | if code <= 0 { 56 | code = 500 57 | } 58 | 59 | return &DestroyOneDefault{ 60 | _statusCode: code, 61 | } 62 | } 63 | 64 | // WithStatusCode adds the status to the destroy one default response 65 | func (o *DestroyOneDefault) WithStatusCode(code int) *DestroyOneDefault { 66 | o._statusCode = code 67 | return o 68 | } 69 | 70 | // SetStatusCode sets the status to the destroy one default response 71 | func (o *DestroyOneDefault) SetStatusCode(code int) { 72 | o._statusCode = code 73 | } 74 | 75 | // WithPayload adds the payload to the destroy one default response 76 | func (o *DestroyOneDefault) WithPayload(payload *models.Error) *DestroyOneDefault { 77 | o.Payload = payload 78 | return o 79 | } 80 | 81 | // SetPayload sets the payload to the destroy one default response 82 | func (o *DestroyOneDefault) SetPayload(payload *models.Error) { 83 | o.Payload = payload 84 | } 85 | 86 | // WriteResponse to the client 87 | func (o *DestroyOneDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 88 | 89 | rw.WriteHeader(o._statusCode) 90 | if o.Payload != nil { 91 | payload := o.Payload 92 | if err := producer.Produce(rw, payload); err != nil { 93 | panic(err) // let the recovery middleware deal with this 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /restapi/operations/todos/destroy_one_urlbuilder.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "errors" 10 | "net/url" 11 | golangswaggerpaths "path" 12 | "strings" 13 | 14 | "github.com/go-openapi/swag" 15 | ) 16 | 17 | // DestroyOneURL generates an URL for the destroy one operation 18 | type DestroyOneURL struct { 19 | ID int64 20 | 21 | _basePath string 22 | // avoid unkeyed usage 23 | _ struct{} 24 | } 25 | 26 | // WithBasePath sets the base path for this url builder, only required when it's different from the 27 | // base path specified in the swagger spec. 28 | // When the value of the base path is an empty string 29 | func (o *DestroyOneURL) WithBasePath(bp string) *DestroyOneURL { 30 | o.SetBasePath(bp) 31 | return o 32 | } 33 | 34 | // SetBasePath sets the base path for this url builder, only required when it's different from the 35 | // base path specified in the swagger spec. 36 | // When the value of the base path is an empty string 37 | func (o *DestroyOneURL) SetBasePath(bp string) { 38 | o._basePath = bp 39 | } 40 | 41 | // Build a url path and query string 42 | func (o *DestroyOneURL) Build() (*url.URL, error) { 43 | var _result url.URL 44 | 45 | var _path = "/{id}" 46 | 47 | id := swag.FormatInt64(o.ID) 48 | if id != "" { 49 | _path = strings.Replace(_path, "{id}", id, -1) 50 | } else { 51 | return nil, errors.New("id is required on DestroyOneURL") 52 | } 53 | 54 | _basePath := o._basePath 55 | _result.Path = golangswaggerpaths.Join(_basePath, _path) 56 | 57 | return &_result, nil 58 | } 59 | 60 | // Must is a helper function to panic when the url builder returns an error 61 | func (o *DestroyOneURL) Must(u *url.URL, err error) *url.URL { 62 | if err != nil { 63 | panic(err) 64 | } 65 | if u == nil { 66 | panic("url can't be nil") 67 | } 68 | return u 69 | } 70 | 71 | // String returns the string representation of the path with query string 72 | func (o *DestroyOneURL) String() string { 73 | return o.Must(o.Build()).String() 74 | } 75 | 76 | // BuildFull builds a full url with scheme, host, path and query string 77 | func (o *DestroyOneURL) BuildFull(scheme, host string) (*url.URL, error) { 78 | if scheme == "" { 79 | return nil, errors.New("scheme is required for a full url on DestroyOneURL") 80 | } 81 | if host == "" { 82 | return nil, errors.New("host is required for a full url on DestroyOneURL") 83 | } 84 | 85 | base, err := o.Build() 86 | if err != nil { 87 | return nil, err 88 | } 89 | 90 | base.Scheme = scheme 91 | base.Host = host 92 | return base, nil 93 | } 94 | 95 | // StringFull returns the string representation of a complete url 96 | func (o *DestroyOneURL) StringFull(scheme, host string) string { 97 | return o.Must(o.BuildFull(scheme, host)).String() 98 | } 99 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todo.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | middleware "github.com/go-openapi/runtime/middleware" 12 | ) 13 | 14 | // FindTodoHandlerFunc turns a function with the right signature into a find todo handler 15 | type FindTodoHandlerFunc func(FindTodoParams) middleware.Responder 16 | 17 | // Handle executing the request and returning a response 18 | func (fn FindTodoHandlerFunc) Handle(params FindTodoParams) middleware.Responder { 19 | return fn(params) 20 | } 21 | 22 | // FindTodoHandler interface for that can handle valid find todo params 23 | type FindTodoHandler interface { 24 | Handle(FindTodoParams) middleware.Responder 25 | } 26 | 27 | // NewFindTodo creates a new http.Handler for the find todo operation 28 | func NewFindTodo(ctx *middleware.Context, handler FindTodoHandler) *FindTodo { 29 | return &FindTodo{Context: ctx, Handler: handler} 30 | } 31 | 32 | /*FindTodo swagger:route GET /{id} todos findTodo 33 | 34 | FindTodo find todo API 35 | 36 | */ 37 | type FindTodo struct { 38 | Context *middleware.Context 39 | Handler FindTodoHandler 40 | } 41 | 42 | func (o *FindTodo) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 43 | route, rCtx, _ := o.Context.RouteInfo(r) 44 | if rCtx != nil { 45 | r = rCtx 46 | } 47 | var Params = NewFindTodoParams() 48 | 49 | if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params 50 | o.Context.Respond(rw, r, route.Produces, route, err) 51 | return 52 | } 53 | 54 | res := o.Handler.Handle(Params) // actually handle the request 55 | 56 | o.Context.Respond(rw, r, route.Produces, route, res) 57 | 58 | } 59 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todo_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/errors" 12 | "github.com/go-openapi/runtime/middleware" 13 | "github.com/go-openapi/swag" 14 | 15 | strfmt "github.com/go-openapi/strfmt" 16 | ) 17 | 18 | // NewFindTodoParams creates a new FindTodoParams object 19 | // no default values defined in spec. 20 | func NewFindTodoParams() FindTodoParams { 21 | 22 | return FindTodoParams{} 23 | } 24 | 25 | // FindTodoParams contains all the bound params for the find todo operation 26 | // typically these are obtained from a http.Request 27 | // 28 | // swagger:parameters findTodo 29 | type FindTodoParams struct { 30 | 31 | // HTTP Request Object 32 | HTTPRequest *http.Request `json:"-"` 33 | 34 | /* 35 | Required: true 36 | In: path 37 | */ 38 | ID int64 39 | } 40 | 41 | // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface 42 | // for simple values it will use straight method calls. 43 | // 44 | // To ensure default values, the struct must have been initialized with NewFindTodoParams() beforehand. 45 | func (o *FindTodoParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { 46 | var res []error 47 | 48 | o.HTTPRequest = r 49 | 50 | rID, rhkID, _ := route.Params.GetOK("id") 51 | if err := o.bindID(rID, rhkID, route.Formats); err != nil { 52 | res = append(res, err) 53 | } 54 | 55 | if len(res) > 0 { 56 | return errors.CompositeValidationError(res...) 57 | } 58 | return nil 59 | } 60 | 61 | // bindID binds and validates parameter ID from path. 62 | func (o *FindTodoParams) bindID(rawData []string, hasKey bool, formats strfmt.Registry) error { 63 | var raw string 64 | if len(rawData) > 0 { 65 | raw = rawData[len(rawData)-1] 66 | } 67 | 68 | // Required: true 69 | // Parameter is provided by construction from the route 70 | 71 | value, err := swag.ConvertInt64(raw) 72 | if err != nil { 73 | return errors.InvalidType("id", "path", "int64", raw) 74 | } 75 | o.ID = value 76 | 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todo_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/runtime" 12 | 13 | models "github.com/spkane/todo-for-terraform/models" 14 | ) 15 | 16 | // FindTodoOKCode is the HTTP code returned for type FindTodoOK 17 | const FindTodoOKCode int = 200 18 | 19 | /*FindTodoOK list the todo 20 | 21 | swagger:response findTodoOK 22 | */ 23 | type FindTodoOK struct { 24 | 25 | /* 26 | In: Body 27 | */ 28 | Payload []*models.Item `json:"body,omitempty"` 29 | } 30 | 31 | // NewFindTodoOK creates FindTodoOK with default headers values 32 | func NewFindTodoOK() *FindTodoOK { 33 | 34 | return &FindTodoOK{} 35 | } 36 | 37 | // WithPayload adds the payload to the find todo o k response 38 | func (o *FindTodoOK) WithPayload(payload []*models.Item) *FindTodoOK { 39 | o.Payload = payload 40 | return o 41 | } 42 | 43 | // SetPayload sets the payload to the find todo o k response 44 | func (o *FindTodoOK) SetPayload(payload []*models.Item) { 45 | o.Payload = payload 46 | } 47 | 48 | // WriteResponse to the client 49 | func (o *FindTodoOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 50 | 51 | rw.WriteHeader(200) 52 | payload := o.Payload 53 | if payload == nil { 54 | // return empty array 55 | payload = make([]*models.Item, 0, 50) 56 | } 57 | 58 | if err := producer.Produce(rw, payload); err != nil { 59 | panic(err) // let the recovery middleware deal with this 60 | } 61 | } 62 | 63 | /*FindTodoDefault generic error response 64 | 65 | swagger:response findTodoDefault 66 | */ 67 | type FindTodoDefault struct { 68 | _statusCode int 69 | 70 | /* 71 | In: Body 72 | */ 73 | Payload *models.Error `json:"body,omitempty"` 74 | } 75 | 76 | // NewFindTodoDefault creates FindTodoDefault with default headers values 77 | func NewFindTodoDefault(code int) *FindTodoDefault { 78 | if code <= 0 { 79 | code = 500 80 | } 81 | 82 | return &FindTodoDefault{ 83 | _statusCode: code, 84 | } 85 | } 86 | 87 | // WithStatusCode adds the status to the find todo default response 88 | func (o *FindTodoDefault) WithStatusCode(code int) *FindTodoDefault { 89 | o._statusCode = code 90 | return o 91 | } 92 | 93 | // SetStatusCode sets the status to the find todo default response 94 | func (o *FindTodoDefault) SetStatusCode(code int) { 95 | o._statusCode = code 96 | } 97 | 98 | // WithPayload adds the payload to the find todo default response 99 | func (o *FindTodoDefault) WithPayload(payload *models.Error) *FindTodoDefault { 100 | o.Payload = payload 101 | return o 102 | } 103 | 104 | // SetPayload sets the payload to the find todo default response 105 | func (o *FindTodoDefault) SetPayload(payload *models.Error) { 106 | o.Payload = payload 107 | } 108 | 109 | // WriteResponse to the client 110 | func (o *FindTodoDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 111 | 112 | rw.WriteHeader(o._statusCode) 113 | if o.Payload != nil { 114 | payload := o.Payload 115 | if err := producer.Produce(rw, payload); err != nil { 116 | panic(err) // let the recovery middleware deal with this 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todo_urlbuilder.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "errors" 10 | "net/url" 11 | golangswaggerpaths "path" 12 | "strings" 13 | 14 | "github.com/go-openapi/swag" 15 | ) 16 | 17 | // FindTodoURL generates an URL for the find todo operation 18 | type FindTodoURL struct { 19 | ID int64 20 | 21 | _basePath string 22 | // avoid unkeyed usage 23 | _ struct{} 24 | } 25 | 26 | // WithBasePath sets the base path for this url builder, only required when it's different from the 27 | // base path specified in the swagger spec. 28 | // When the value of the base path is an empty string 29 | func (o *FindTodoURL) WithBasePath(bp string) *FindTodoURL { 30 | o.SetBasePath(bp) 31 | return o 32 | } 33 | 34 | // SetBasePath sets the base path for this url builder, only required when it's different from the 35 | // base path specified in the swagger spec. 36 | // When the value of the base path is an empty string 37 | func (o *FindTodoURL) SetBasePath(bp string) { 38 | o._basePath = bp 39 | } 40 | 41 | // Build a url path and query string 42 | func (o *FindTodoURL) Build() (*url.URL, error) { 43 | var _result url.URL 44 | 45 | var _path = "/{id}" 46 | 47 | id := swag.FormatInt64(o.ID) 48 | if id != "" { 49 | _path = strings.Replace(_path, "{id}", id, -1) 50 | } else { 51 | return nil, errors.New("id is required on FindTodoURL") 52 | } 53 | 54 | _basePath := o._basePath 55 | _result.Path = golangswaggerpaths.Join(_basePath, _path) 56 | 57 | return &_result, nil 58 | } 59 | 60 | // Must is a helper function to panic when the url builder returns an error 61 | func (o *FindTodoURL) Must(u *url.URL, err error) *url.URL { 62 | if err != nil { 63 | panic(err) 64 | } 65 | if u == nil { 66 | panic("url can't be nil") 67 | } 68 | return u 69 | } 70 | 71 | // String returns the string representation of the path with query string 72 | func (o *FindTodoURL) String() string { 73 | return o.Must(o.Build()).String() 74 | } 75 | 76 | // BuildFull builds a full url with scheme, host, path and query string 77 | func (o *FindTodoURL) BuildFull(scheme, host string) (*url.URL, error) { 78 | if scheme == "" { 79 | return nil, errors.New("scheme is required for a full url on FindTodoURL") 80 | } 81 | if host == "" { 82 | return nil, errors.New("host is required for a full url on FindTodoURL") 83 | } 84 | 85 | base, err := o.Build() 86 | if err != nil { 87 | return nil, err 88 | } 89 | 90 | base.Scheme = scheme 91 | base.Host = host 92 | return base, nil 93 | } 94 | 95 | // StringFull returns the string representation of a complete url 96 | func (o *FindTodoURL) StringFull(scheme, host string) string { 97 | return o.Must(o.BuildFull(scheme, host)).String() 98 | } 99 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todos.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | middleware "github.com/go-openapi/runtime/middleware" 12 | ) 13 | 14 | // FindTodosHandlerFunc turns a function with the right signature into a find todos handler 15 | type FindTodosHandlerFunc func(FindTodosParams) middleware.Responder 16 | 17 | // Handle executing the request and returning a response 18 | func (fn FindTodosHandlerFunc) Handle(params FindTodosParams) middleware.Responder { 19 | return fn(params) 20 | } 21 | 22 | // FindTodosHandler interface for that can handle valid find todos params 23 | type FindTodosHandler interface { 24 | Handle(FindTodosParams) middleware.Responder 25 | } 26 | 27 | // NewFindTodos creates a new http.Handler for the find todos operation 28 | func NewFindTodos(ctx *middleware.Context, handler FindTodosHandler) *FindTodos { 29 | return &FindTodos{Context: ctx, Handler: handler} 30 | } 31 | 32 | /*FindTodos swagger:route GET / todos findTodos 33 | 34 | FindTodos find todos API 35 | 36 | */ 37 | type FindTodos struct { 38 | Context *middleware.Context 39 | Handler FindTodosHandler 40 | } 41 | 42 | func (o *FindTodos) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 43 | route, rCtx, _ := o.Context.RouteInfo(r) 44 | if rCtx != nil { 45 | r = rCtx 46 | } 47 | var Params = NewFindTodosParams() 48 | 49 | if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params 50 | o.Context.Respond(rw, r, route.Produces, route, err) 51 | return 52 | } 53 | 54 | res := o.Handler.Handle(Params) // actually handle the request 55 | 56 | o.Context.Respond(rw, r, route.Produces, route, res) 57 | 58 | } 59 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todos_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/errors" 12 | "github.com/go-openapi/runtime" 13 | "github.com/go-openapi/runtime/middleware" 14 | "github.com/go-openapi/swag" 15 | 16 | strfmt "github.com/go-openapi/strfmt" 17 | ) 18 | 19 | // NewFindTodosParams creates a new FindTodosParams object 20 | // with the default values initialized. 21 | func NewFindTodosParams() FindTodosParams { 22 | 23 | var ( 24 | // initialize parameters with default values 25 | 26 | limitDefault = int32(20) 27 | ) 28 | 29 | return FindTodosParams{ 30 | Limit: &limitDefault, 31 | } 32 | } 33 | 34 | // FindTodosParams contains all the bound params for the find todos operation 35 | // typically these are obtained from a http.Request 36 | // 37 | // swagger:parameters findTodos 38 | type FindTodosParams struct { 39 | 40 | // HTTP Request Object 41 | HTTPRequest *http.Request `json:"-"` 42 | 43 | /* 44 | In: query 45 | Default: 20 46 | */ 47 | Limit *int32 48 | /* 49 | In: query 50 | */ 51 | Since *int64 52 | } 53 | 54 | // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface 55 | // for simple values it will use straight method calls. 56 | // 57 | // To ensure default values, the struct must have been initialized with NewFindTodosParams() beforehand. 58 | func (o *FindTodosParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { 59 | var res []error 60 | 61 | o.HTTPRequest = r 62 | 63 | qs := runtime.Values(r.URL.Query()) 64 | 65 | qLimit, qhkLimit, _ := qs.GetOK("limit") 66 | if err := o.bindLimit(qLimit, qhkLimit, route.Formats); err != nil { 67 | res = append(res, err) 68 | } 69 | 70 | qSince, qhkSince, _ := qs.GetOK("since") 71 | if err := o.bindSince(qSince, qhkSince, route.Formats); err != nil { 72 | res = append(res, err) 73 | } 74 | 75 | if len(res) > 0 { 76 | return errors.CompositeValidationError(res...) 77 | } 78 | return nil 79 | } 80 | 81 | // bindLimit binds and validates parameter Limit from query. 82 | func (o *FindTodosParams) bindLimit(rawData []string, hasKey bool, formats strfmt.Registry) error { 83 | var raw string 84 | if len(rawData) > 0 { 85 | raw = rawData[len(rawData)-1] 86 | } 87 | 88 | // Required: false 89 | // AllowEmptyValue: false 90 | if raw == "" { // empty values pass all other validations 91 | // Default values have been previously initialized by NewFindTodosParams() 92 | return nil 93 | } 94 | 95 | value, err := swag.ConvertInt32(raw) 96 | if err != nil { 97 | return errors.InvalidType("limit", "query", "int32", raw) 98 | } 99 | o.Limit = &value 100 | 101 | return nil 102 | } 103 | 104 | // bindSince binds and validates parameter Since from query. 105 | func (o *FindTodosParams) bindSince(rawData []string, hasKey bool, formats strfmt.Registry) error { 106 | var raw string 107 | if len(rawData) > 0 { 108 | raw = rawData[len(rawData)-1] 109 | } 110 | 111 | // Required: false 112 | // AllowEmptyValue: false 113 | if raw == "" { // empty values pass all other validations 114 | return nil 115 | } 116 | 117 | value, err := swag.ConvertInt64(raw) 118 | if err != nil { 119 | return errors.InvalidType("since", "query", "int64", raw) 120 | } 121 | o.Since = &value 122 | 123 | return nil 124 | } 125 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todos_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/runtime" 12 | 13 | models "github.com/spkane/todo-for-terraform/models" 14 | ) 15 | 16 | // FindTodosOKCode is the HTTP code returned for type FindTodosOK 17 | const FindTodosOKCode int = 200 18 | 19 | /*FindTodosOK list the todo operations 20 | 21 | swagger:response findTodosOK 22 | */ 23 | type FindTodosOK struct { 24 | 25 | /* 26 | In: Body 27 | */ 28 | Payload []*models.Item `json:"body,omitempty"` 29 | } 30 | 31 | // NewFindTodosOK creates FindTodosOK with default headers values 32 | func NewFindTodosOK() *FindTodosOK { 33 | 34 | return &FindTodosOK{} 35 | } 36 | 37 | // WithPayload adds the payload to the find todos o k response 38 | func (o *FindTodosOK) WithPayload(payload []*models.Item) *FindTodosOK { 39 | o.Payload = payload 40 | return o 41 | } 42 | 43 | // SetPayload sets the payload to the find todos o k response 44 | func (o *FindTodosOK) SetPayload(payload []*models.Item) { 45 | o.Payload = payload 46 | } 47 | 48 | // WriteResponse to the client 49 | func (o *FindTodosOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 50 | 51 | rw.WriteHeader(200) 52 | payload := o.Payload 53 | if payload == nil { 54 | // return empty array 55 | payload = make([]*models.Item, 0, 50) 56 | } 57 | 58 | if err := producer.Produce(rw, payload); err != nil { 59 | panic(err) // let the recovery middleware deal with this 60 | } 61 | } 62 | 63 | /*FindTodosDefault generic error response 64 | 65 | swagger:response findTodosDefault 66 | */ 67 | type FindTodosDefault struct { 68 | _statusCode int 69 | 70 | /* 71 | In: Body 72 | */ 73 | Payload *models.Error `json:"body,omitempty"` 74 | } 75 | 76 | // NewFindTodosDefault creates FindTodosDefault with default headers values 77 | func NewFindTodosDefault(code int) *FindTodosDefault { 78 | if code <= 0 { 79 | code = 500 80 | } 81 | 82 | return &FindTodosDefault{ 83 | _statusCode: code, 84 | } 85 | } 86 | 87 | // WithStatusCode adds the status to the find todos default response 88 | func (o *FindTodosDefault) WithStatusCode(code int) *FindTodosDefault { 89 | o._statusCode = code 90 | return o 91 | } 92 | 93 | // SetStatusCode sets the status to the find todos default response 94 | func (o *FindTodosDefault) SetStatusCode(code int) { 95 | o._statusCode = code 96 | } 97 | 98 | // WithPayload adds the payload to the find todos default response 99 | func (o *FindTodosDefault) WithPayload(payload *models.Error) *FindTodosDefault { 100 | o.Payload = payload 101 | return o 102 | } 103 | 104 | // SetPayload sets the payload to the find todos default response 105 | func (o *FindTodosDefault) SetPayload(payload *models.Error) { 106 | o.Payload = payload 107 | } 108 | 109 | // WriteResponse to the client 110 | func (o *FindTodosDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 111 | 112 | rw.WriteHeader(o._statusCode) 113 | if o.Payload != nil { 114 | payload := o.Payload 115 | if err := producer.Produce(rw, payload); err != nil { 116 | panic(err) // let the recovery middleware deal with this 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /restapi/operations/todos/find_todos_urlbuilder.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "errors" 10 | "net/url" 11 | golangswaggerpaths "path" 12 | 13 | "github.com/go-openapi/swag" 14 | ) 15 | 16 | // FindTodosURL generates an URL for the find todos operation 17 | type FindTodosURL struct { 18 | Limit *int32 19 | Since *int64 20 | 21 | _basePath string 22 | // avoid unkeyed usage 23 | _ struct{} 24 | } 25 | 26 | // WithBasePath sets the base path for this url builder, only required when it's different from the 27 | // base path specified in the swagger spec. 28 | // When the value of the base path is an empty string 29 | func (o *FindTodosURL) WithBasePath(bp string) *FindTodosURL { 30 | o.SetBasePath(bp) 31 | return o 32 | } 33 | 34 | // SetBasePath sets the base path for this url builder, only required when it's different from the 35 | // base path specified in the swagger spec. 36 | // When the value of the base path is an empty string 37 | func (o *FindTodosURL) SetBasePath(bp string) { 38 | o._basePath = bp 39 | } 40 | 41 | // Build a url path and query string 42 | func (o *FindTodosURL) Build() (*url.URL, error) { 43 | var _result url.URL 44 | 45 | var _path = "/" 46 | 47 | _basePath := o._basePath 48 | _result.Path = golangswaggerpaths.Join(_basePath, _path) 49 | 50 | qs := make(url.Values) 51 | 52 | var limitQ string 53 | if o.Limit != nil { 54 | limitQ = swag.FormatInt32(*o.Limit) 55 | } 56 | if limitQ != "" { 57 | qs.Set("limit", limitQ) 58 | } 59 | 60 | var sinceQ string 61 | if o.Since != nil { 62 | sinceQ = swag.FormatInt64(*o.Since) 63 | } 64 | if sinceQ != "" { 65 | qs.Set("since", sinceQ) 66 | } 67 | 68 | _result.RawQuery = qs.Encode() 69 | 70 | return &_result, nil 71 | } 72 | 73 | // Must is a helper function to panic when the url builder returns an error 74 | func (o *FindTodosURL) Must(u *url.URL, err error) *url.URL { 75 | if err != nil { 76 | panic(err) 77 | } 78 | if u == nil { 79 | panic("url can't be nil") 80 | } 81 | return u 82 | } 83 | 84 | // String returns the string representation of the path with query string 85 | func (o *FindTodosURL) String() string { 86 | return o.Must(o.Build()).String() 87 | } 88 | 89 | // BuildFull builds a full url with scheme, host, path and query string 90 | func (o *FindTodosURL) BuildFull(scheme, host string) (*url.URL, error) { 91 | if scheme == "" { 92 | return nil, errors.New("scheme is required for a full url on FindTodosURL") 93 | } 94 | if host == "" { 95 | return nil, errors.New("host is required for a full url on FindTodosURL") 96 | } 97 | 98 | base, err := o.Build() 99 | if err != nil { 100 | return nil, err 101 | } 102 | 103 | base.Scheme = scheme 104 | base.Host = host 105 | return base, nil 106 | } 107 | 108 | // StringFull returns the string representation of a complete url 109 | func (o *FindTodosURL) StringFull(scheme, host string) string { 110 | return o.Must(o.BuildFull(scheme, host)).String() 111 | } 112 | -------------------------------------------------------------------------------- /restapi/operations/todos/update_one.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | middleware "github.com/go-openapi/runtime/middleware" 12 | ) 13 | 14 | // UpdateOneHandlerFunc turns a function with the right signature into a update one handler 15 | type UpdateOneHandlerFunc func(UpdateOneParams) middleware.Responder 16 | 17 | // Handle executing the request and returning a response 18 | func (fn UpdateOneHandlerFunc) Handle(params UpdateOneParams) middleware.Responder { 19 | return fn(params) 20 | } 21 | 22 | // UpdateOneHandler interface for that can handle valid update one params 23 | type UpdateOneHandler interface { 24 | Handle(UpdateOneParams) middleware.Responder 25 | } 26 | 27 | // NewUpdateOne creates a new http.Handler for the update one operation 28 | func NewUpdateOne(ctx *middleware.Context, handler UpdateOneHandler) *UpdateOne { 29 | return &UpdateOne{Context: ctx, Handler: handler} 30 | } 31 | 32 | /*UpdateOne swagger:route PUT /{id} todos updateOne 33 | 34 | UpdateOne update one API 35 | 36 | */ 37 | type UpdateOne struct { 38 | Context *middleware.Context 39 | Handler UpdateOneHandler 40 | } 41 | 42 | func (o *UpdateOne) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 43 | route, rCtx, _ := o.Context.RouteInfo(r) 44 | if rCtx != nil { 45 | r = rCtx 46 | } 47 | var Params = NewUpdateOneParams() 48 | 49 | if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params 50 | o.Context.Respond(rw, r, route.Produces, route, err) 51 | return 52 | } 53 | 54 | res := o.Handler.Handle(Params) // actually handle the request 55 | 56 | o.Context.Respond(rw, r, route.Produces, route, res) 57 | 58 | } 59 | -------------------------------------------------------------------------------- /restapi/operations/todos/update_one_parameters.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/errors" 12 | "github.com/go-openapi/runtime" 13 | "github.com/go-openapi/runtime/middleware" 14 | "github.com/go-openapi/swag" 15 | 16 | strfmt "github.com/go-openapi/strfmt" 17 | 18 | models "github.com/spkane/todo-for-terraform/models" 19 | ) 20 | 21 | // NewUpdateOneParams creates a new UpdateOneParams object 22 | // no default values defined in spec. 23 | func NewUpdateOneParams() UpdateOneParams { 24 | 25 | return UpdateOneParams{} 26 | } 27 | 28 | // UpdateOneParams contains all the bound params for the update one operation 29 | // typically these are obtained from a http.Request 30 | // 31 | // swagger:parameters updateOne 32 | type UpdateOneParams struct { 33 | 34 | // HTTP Request Object 35 | HTTPRequest *http.Request `json:"-"` 36 | 37 | /* 38 | In: body 39 | */ 40 | Body *models.Item 41 | /* 42 | Required: true 43 | In: path 44 | */ 45 | ID int64 46 | } 47 | 48 | // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface 49 | // for simple values it will use straight method calls. 50 | // 51 | // To ensure default values, the struct must have been initialized with NewUpdateOneParams() beforehand. 52 | func (o *UpdateOneParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { 53 | var res []error 54 | 55 | o.HTTPRequest = r 56 | 57 | if runtime.HasBody(r) { 58 | defer r.Body.Close() 59 | var body models.Item 60 | if err := route.Consumer.Consume(r.Body, &body); err != nil { 61 | res = append(res, errors.NewParseError("body", "body", "", err)) 62 | } else { 63 | // validate body object 64 | if err := body.Validate(route.Formats); err != nil { 65 | res = append(res, err) 66 | } 67 | 68 | if len(res) == 0 { 69 | o.Body = &body 70 | } 71 | } 72 | } 73 | rID, rhkID, _ := route.Params.GetOK("id") 74 | if err := o.bindID(rID, rhkID, route.Formats); err != nil { 75 | res = append(res, err) 76 | } 77 | 78 | if len(res) > 0 { 79 | return errors.CompositeValidationError(res...) 80 | } 81 | return nil 82 | } 83 | 84 | // bindID binds and validates parameter ID from path. 85 | func (o *UpdateOneParams) bindID(rawData []string, hasKey bool, formats strfmt.Registry) error { 86 | var raw string 87 | if len(rawData) > 0 { 88 | raw = rawData[len(rawData)-1] 89 | } 90 | 91 | // Required: true 92 | // Parameter is provided by construction from the route 93 | 94 | value, err := swag.ConvertInt64(raw) 95 | if err != nil { 96 | return errors.InvalidType("id", "path", "int64", raw) 97 | } 98 | o.ID = value 99 | 100 | return nil 101 | } 102 | -------------------------------------------------------------------------------- /restapi/operations/todos/update_one_responses.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the swagger generate command 7 | 8 | import ( 9 | "net/http" 10 | 11 | "github.com/go-openapi/runtime" 12 | 13 | models "github.com/spkane/todo-for-terraform/models" 14 | ) 15 | 16 | // UpdateOneOKCode is the HTTP code returned for type UpdateOneOK 17 | const UpdateOneOKCode int = 200 18 | 19 | /*UpdateOneOK OK 20 | 21 | swagger:response updateOneOK 22 | */ 23 | type UpdateOneOK struct { 24 | 25 | /* 26 | In: Body 27 | */ 28 | Payload *models.Item `json:"body,omitempty"` 29 | } 30 | 31 | // NewUpdateOneOK creates UpdateOneOK with default headers values 32 | func NewUpdateOneOK() *UpdateOneOK { 33 | 34 | return &UpdateOneOK{} 35 | } 36 | 37 | // WithPayload adds the payload to the update one o k response 38 | func (o *UpdateOneOK) WithPayload(payload *models.Item) *UpdateOneOK { 39 | o.Payload = payload 40 | return o 41 | } 42 | 43 | // SetPayload sets the payload to the update one o k response 44 | func (o *UpdateOneOK) SetPayload(payload *models.Item) { 45 | o.Payload = payload 46 | } 47 | 48 | // WriteResponse to the client 49 | func (o *UpdateOneOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 50 | 51 | rw.WriteHeader(200) 52 | if o.Payload != nil { 53 | payload := o.Payload 54 | if err := producer.Produce(rw, payload); err != nil { 55 | panic(err) // let the recovery middleware deal with this 56 | } 57 | } 58 | } 59 | 60 | /*UpdateOneDefault error 61 | 62 | swagger:response updateOneDefault 63 | */ 64 | type UpdateOneDefault struct { 65 | _statusCode int 66 | 67 | /* 68 | In: Body 69 | */ 70 | Payload *models.Error `json:"body,omitempty"` 71 | } 72 | 73 | // NewUpdateOneDefault creates UpdateOneDefault with default headers values 74 | func NewUpdateOneDefault(code int) *UpdateOneDefault { 75 | if code <= 0 { 76 | code = 500 77 | } 78 | 79 | return &UpdateOneDefault{ 80 | _statusCode: code, 81 | } 82 | } 83 | 84 | // WithStatusCode adds the status to the update one default response 85 | func (o *UpdateOneDefault) WithStatusCode(code int) *UpdateOneDefault { 86 | o._statusCode = code 87 | return o 88 | } 89 | 90 | // SetStatusCode sets the status to the update one default response 91 | func (o *UpdateOneDefault) SetStatusCode(code int) { 92 | o._statusCode = code 93 | } 94 | 95 | // WithPayload adds the payload to the update one default response 96 | func (o *UpdateOneDefault) WithPayload(payload *models.Error) *UpdateOneDefault { 97 | o.Payload = payload 98 | return o 99 | } 100 | 101 | // SetPayload sets the payload to the update one default response 102 | func (o *UpdateOneDefault) SetPayload(payload *models.Error) { 103 | o.Payload = payload 104 | } 105 | 106 | // WriteResponse to the client 107 | func (o *UpdateOneDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { 108 | 109 | rw.WriteHeader(o._statusCode) 110 | if o.Payload != nil { 111 | payload := o.Payload 112 | if err := producer.Produce(rw, payload); err != nil { 113 | panic(err) // let the recovery middleware deal with this 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /restapi/operations/todos/update_one_urlbuilder.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package todos 4 | 5 | // This file was generated by the swagger tool. 6 | // Editing this file might prove futile when you re-run the generate command 7 | 8 | import ( 9 | "errors" 10 | "net/url" 11 | golangswaggerpaths "path" 12 | "strings" 13 | 14 | "github.com/go-openapi/swag" 15 | ) 16 | 17 | // UpdateOneURL generates an URL for the update one operation 18 | type UpdateOneURL struct { 19 | ID int64 20 | 21 | _basePath string 22 | // avoid unkeyed usage 23 | _ struct{} 24 | } 25 | 26 | // WithBasePath sets the base path for this url builder, only required when it's different from the 27 | // base path specified in the swagger spec. 28 | // When the value of the base path is an empty string 29 | func (o *UpdateOneURL) WithBasePath(bp string) *UpdateOneURL { 30 | o.SetBasePath(bp) 31 | return o 32 | } 33 | 34 | // SetBasePath sets the base path for this url builder, only required when it's different from the 35 | // base path specified in the swagger spec. 36 | // When the value of the base path is an empty string 37 | func (o *UpdateOneURL) SetBasePath(bp string) { 38 | o._basePath = bp 39 | } 40 | 41 | // Build a url path and query string 42 | func (o *UpdateOneURL) Build() (*url.URL, error) { 43 | var _result url.URL 44 | 45 | var _path = "/{id}" 46 | 47 | id := swag.FormatInt64(o.ID) 48 | if id != "" { 49 | _path = strings.Replace(_path, "{id}", id, -1) 50 | } else { 51 | return nil, errors.New("id is required on UpdateOneURL") 52 | } 53 | 54 | _basePath := o._basePath 55 | _result.Path = golangswaggerpaths.Join(_basePath, _path) 56 | 57 | return &_result, nil 58 | } 59 | 60 | // Must is a helper function to panic when the url builder returns an error 61 | func (o *UpdateOneURL) Must(u *url.URL, err error) *url.URL { 62 | if err != nil { 63 | panic(err) 64 | } 65 | if u == nil { 66 | panic("url can't be nil") 67 | } 68 | return u 69 | } 70 | 71 | // String returns the string representation of the path with query string 72 | func (o *UpdateOneURL) String() string { 73 | return o.Must(o.Build()).String() 74 | } 75 | 76 | // BuildFull builds a full url with scheme, host, path and query string 77 | func (o *UpdateOneURL) BuildFull(scheme, host string) (*url.URL, error) { 78 | if scheme == "" { 79 | return nil, errors.New("scheme is required for a full url on UpdateOneURL") 80 | } 81 | if host == "" { 82 | return nil, errors.New("host is required for a full url on UpdateOneURL") 83 | } 84 | 85 | base, err := o.Build() 86 | if err != nil { 87 | return nil, err 88 | } 89 | 90 | base.Scheme = scheme 91 | base.Host = host 92 | return base, nil 93 | } 94 | 95 | // StringFull returns the string representation of a complete url 96 | func (o *UpdateOneURL) StringFull(scheme, host string) string { 97 | return o.Must(o.BuildFull(scheme, host)).String() 98 | } 99 | -------------------------------------------------------------------------------- /restapi/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-swagger; DO NOT EDIT. 2 | 3 | package restapi 4 | 5 | import ( 6 | "context" 7 | "crypto/tls" 8 | "crypto/x509" 9 | "errors" 10 | "fmt" 11 | "io/ioutil" 12 | "log" 13 | "net" 14 | "net/http" 15 | "os" 16 | "os/signal" 17 | "strconv" 18 | "sync" 19 | "sync/atomic" 20 | "syscall" 21 | "time" 22 | 23 | "github.com/go-openapi/runtime/flagext" 24 | "github.com/go-openapi/swag" 25 | flags "github.com/jessevdk/go-flags" 26 | "golang.org/x/net/netutil" 27 | 28 | "github.com/spkane/todo-for-terraform/restapi/operations" 29 | ) 30 | 31 | const ( 32 | schemeHTTP = "http" 33 | schemeHTTPS = "https" 34 | schemeUnix = "unix" 35 | ) 36 | 37 | var defaultSchemes []string 38 | 39 | func init() { 40 | defaultSchemes = []string{ 41 | schemeHTTP, 42 | } 43 | } 44 | 45 | // NewServer creates a new api todo list server but does not configure it 46 | func NewServer(api *operations.TodoListAPI) *Server { 47 | s := new(Server) 48 | 49 | s.shutdown = make(chan struct{}) 50 | s.api = api 51 | s.interrupt = make(chan os.Signal, 1) 52 | return s 53 | } 54 | 55 | // ConfigureAPI configures the API and handlers. 56 | func (s *Server) ConfigureAPI() { 57 | if s.api != nil { 58 | s.handler = configureAPI(s.api) 59 | } 60 | } 61 | 62 | // ConfigureFlags configures the additional flags defined by the handlers. Needs to be called before the parser.Parse 63 | func (s *Server) ConfigureFlags() { 64 | if s.api != nil { 65 | configureFlags(s.api) 66 | } 67 | } 68 | 69 | // Server for the todo list API 70 | type Server struct { 71 | EnabledListeners []string `long:"scheme" description:"the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec"` 72 | CleanupTimeout time.Duration `long:"cleanup-timeout" description:"grace period for which to wait before killing idle connections" default:"10s"` 73 | GracefulTimeout time.Duration `long:"graceful-timeout" description:"grace period for which to wait before shutting down the server" default:"15s"` 74 | MaxHeaderSize flagext.ByteSize `long:"max-header-size" description:"controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body." default:"1MiB"` 75 | 76 | SocketPath flags.Filename `long:"socket-path" description:"the unix socket to listen on" default:"/var/run/todo-list.sock"` 77 | domainSocketL net.Listener 78 | 79 | Host string `long:"host" description:"the IP to listen on" default:"localhost" env:"HOST"` 80 | Port int `long:"port" description:"the port to listen on for insecure connections, defaults to a random value" env:"PORT"` 81 | ListenLimit int `long:"listen-limit" description:"limit the number of outstanding requests"` 82 | KeepAlive time.Duration `long:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"` 83 | ReadTimeout time.Duration `long:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"` 84 | WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"60s"` 85 | httpServerL net.Listener 86 | 87 | TLSHost string `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"` 88 | TLSPort int `long:"tls-port" description:"the port to listen on for secure connections, defaults to a random value" env:"TLS_PORT"` 89 | TLSCertificate flags.Filename `long:"tls-certificate" description:"the certificate to use for secure connections" env:"TLS_CERTIFICATE"` 90 | TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure connections" env:"TLS_PRIVATE_KEY"` 91 | TLSCACertificate flags.Filename `long:"tls-ca" description:"the certificate authority file to be used with mutual tls auth" env:"TLS_CA_CERTIFICATE"` 92 | TLSListenLimit int `long:"tls-listen-limit" description:"limit the number of outstanding requests"` 93 | TLSKeepAlive time.Duration `long:"tls-keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)"` 94 | TLSReadTimeout time.Duration `long:"tls-read-timeout" description:"maximum duration before timing out read of the request"` 95 | TLSWriteTimeout time.Duration `long:"tls-write-timeout" description:"maximum duration before timing out write of the response"` 96 | httpsServerL net.Listener 97 | 98 | api *operations.TodoListAPI 99 | handler http.Handler 100 | hasListeners bool 101 | shutdown chan struct{} 102 | shuttingDown int32 103 | interrupted bool 104 | interrupt chan os.Signal 105 | } 106 | 107 | // Logf logs message either via defined user logger or via system one if no user logger is defined. 108 | func (s *Server) Logf(f string, args ...interface{}) { 109 | if s.api != nil && s.api.Logger != nil { 110 | s.api.Logger(f, args...) 111 | } else { 112 | log.Printf(f, args...) 113 | } 114 | } 115 | 116 | // Fatalf logs message either via defined user logger or via system one if no user logger is defined. 117 | // Exits with non-zero status after printing 118 | func (s *Server) Fatalf(f string, args ...interface{}) { 119 | if s.api != nil && s.api.Logger != nil { 120 | s.api.Logger(f, args...) 121 | os.Exit(1) 122 | } else { 123 | log.Fatalf(f, args...) 124 | } 125 | } 126 | 127 | // SetAPI configures the server with the specified API. Needs to be called before Serve 128 | func (s *Server) SetAPI(api *operations.TodoListAPI) { 129 | if api == nil { 130 | s.api = nil 131 | s.handler = nil 132 | return 133 | } 134 | 135 | s.api = api 136 | s.handler = configureAPI(api) 137 | } 138 | 139 | func (s *Server) hasScheme(scheme string) bool { 140 | schemes := s.EnabledListeners 141 | if len(schemes) == 0 { 142 | schemes = defaultSchemes 143 | } 144 | 145 | for _, v := range schemes { 146 | if v == scheme { 147 | return true 148 | } 149 | } 150 | return false 151 | } 152 | 153 | // Serve the api 154 | func (s *Server) Serve() (err error) { 155 | if !s.hasListeners { 156 | if err = s.Listen(); err != nil { 157 | return err 158 | } 159 | } 160 | 161 | // set default handler, if none is set 162 | if s.handler == nil { 163 | if s.api == nil { 164 | return errors.New("can't create the default handler, as no api is set") 165 | } 166 | 167 | s.SetHandler(s.api.Serve(nil)) 168 | } 169 | 170 | wg := new(sync.WaitGroup) 171 | once := new(sync.Once) 172 | signalNotify(s.interrupt) 173 | go handleInterrupt(once, s) 174 | 175 | servers := []*http.Server{} 176 | wg.Add(1) 177 | go s.handleShutdown(wg, &servers) 178 | 179 | if s.hasScheme(schemeUnix) { 180 | domainSocket := new(http.Server) 181 | domainSocket.MaxHeaderBytes = int(s.MaxHeaderSize) 182 | domainSocket.Handler = s.handler 183 | if int64(s.CleanupTimeout) > 0 { 184 | domainSocket.IdleTimeout = s.CleanupTimeout 185 | } 186 | 187 | configureServer(domainSocket, "unix", string(s.SocketPath)) 188 | 189 | servers = append(servers, domainSocket) 190 | wg.Add(1) 191 | s.Logf("Serving todo list at unix://%s", s.SocketPath) 192 | go func(l net.Listener) { 193 | defer wg.Done() 194 | if err := domainSocket.Serve(l); err != nil && err != http.ErrServerClosed { 195 | s.Fatalf("%v", err) 196 | } 197 | s.Logf("Stopped serving todo list at unix://%s", s.SocketPath) 198 | }(s.domainSocketL) 199 | } 200 | 201 | if s.hasScheme(schemeHTTP) { 202 | httpServer := new(http.Server) 203 | httpServer.MaxHeaderBytes = int(s.MaxHeaderSize) 204 | httpServer.ReadTimeout = s.ReadTimeout 205 | httpServer.WriteTimeout = s.WriteTimeout 206 | httpServer.SetKeepAlivesEnabled(int64(s.KeepAlive) > 0) 207 | if s.ListenLimit > 0 { 208 | s.httpServerL = netutil.LimitListener(s.httpServerL, s.ListenLimit) 209 | } 210 | 211 | if int64(s.CleanupTimeout) > 0 { 212 | httpServer.IdleTimeout = s.CleanupTimeout 213 | } 214 | 215 | httpServer.Handler = s.handler 216 | 217 | configureServer(httpServer, "http", s.httpServerL.Addr().String()) 218 | 219 | servers = append(servers, httpServer) 220 | wg.Add(1) 221 | s.Logf("Serving todo list at http://%s", s.httpServerL.Addr()) 222 | go func(l net.Listener) { 223 | defer wg.Done() 224 | if err := httpServer.Serve(l); err != nil && err != http.ErrServerClosed { 225 | s.Fatalf("%v", err) 226 | } 227 | s.Logf("Stopped serving todo list at http://%s", l.Addr()) 228 | }(s.httpServerL) 229 | } 230 | 231 | if s.hasScheme(schemeHTTPS) { 232 | httpsServer := new(http.Server) 233 | httpsServer.MaxHeaderBytes = int(s.MaxHeaderSize) 234 | httpsServer.ReadTimeout = s.TLSReadTimeout 235 | httpsServer.WriteTimeout = s.TLSWriteTimeout 236 | httpsServer.SetKeepAlivesEnabled(int64(s.TLSKeepAlive) > 0) 237 | if s.TLSListenLimit > 0 { 238 | s.httpsServerL = netutil.LimitListener(s.httpsServerL, s.TLSListenLimit) 239 | } 240 | if int64(s.CleanupTimeout) > 0 { 241 | httpsServer.IdleTimeout = s.CleanupTimeout 242 | } 243 | httpsServer.Handler = s.handler 244 | 245 | // Inspired by https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go 246 | httpsServer.TLSConfig = &tls.Config{ 247 | // Causes servers to use Go's default ciphersuite preferences, 248 | // which are tuned to avoid attacks. Does nothing on clients. 249 | PreferServerCipherSuites: true, 250 | // Only use curves which have assembly implementations 251 | // https://github.com/golang/go/tree/master/src/crypto/elliptic 252 | CurvePreferences: []tls.CurveID{tls.CurveP256}, 253 | // Use modern tls mode https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility 254 | NextProtos: []string{"h2", "http/1.1"}, 255 | // https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Only_Support_Strong_Protocols 256 | MinVersion: tls.VersionTLS12, 257 | // These ciphersuites support Forward Secrecy: https://en.wikipedia.org/wiki/Forward_secrecy 258 | CipherSuites: []uint16{ 259 | tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 260 | tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 261 | tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 262 | tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 263 | tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 264 | tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 265 | }, 266 | } 267 | 268 | // build standard config from server options 269 | if s.TLSCertificate != "" && s.TLSCertificateKey != "" { 270 | httpsServer.TLSConfig.Certificates = make([]tls.Certificate, 1) 271 | httpsServer.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(string(s.TLSCertificate), string(s.TLSCertificateKey)) 272 | if err != nil { 273 | return err 274 | } 275 | } 276 | 277 | if s.TLSCACertificate != "" { 278 | // include specified CA certificate 279 | caCert, caCertErr := ioutil.ReadFile(string(s.TLSCACertificate)) 280 | if caCertErr != nil { 281 | return caCertErr 282 | } 283 | caCertPool := x509.NewCertPool() 284 | ok := caCertPool.AppendCertsFromPEM(caCert) 285 | if !ok { 286 | return fmt.Errorf("cannot parse CA certificate") 287 | } 288 | httpsServer.TLSConfig.ClientCAs = caCertPool 289 | httpsServer.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert 290 | } 291 | 292 | // call custom TLS configurator 293 | configureTLS(httpsServer.TLSConfig) 294 | 295 | if len(httpsServer.TLSConfig.Certificates) == 0 && httpsServer.TLSConfig.GetCertificate == nil { 296 | // after standard and custom config are passed, this ends up with no certificate 297 | if s.TLSCertificate == "" { 298 | if s.TLSCertificateKey == "" { 299 | s.Fatalf("the required flags `--tls-certificate` and `--tls-key` were not specified") 300 | } 301 | s.Fatalf("the required flag `--tls-certificate` was not specified") 302 | } 303 | if s.TLSCertificateKey == "" { 304 | s.Fatalf("the required flag `--tls-key` was not specified") 305 | } 306 | // this happens with a wrong custom TLS configurator 307 | s.Fatalf("no certificate was configured for TLS") 308 | } 309 | 310 | // must have at least one certificate or panics 311 | httpsServer.TLSConfig.BuildNameToCertificate() 312 | 313 | configureServer(httpsServer, "https", s.httpsServerL.Addr().String()) 314 | 315 | servers = append(servers, httpsServer) 316 | wg.Add(1) 317 | s.Logf("Serving todo list at https://%s", s.httpsServerL.Addr()) 318 | go func(l net.Listener) { 319 | defer wg.Done() 320 | if err := httpsServer.Serve(l); err != nil && err != http.ErrServerClosed { 321 | s.Fatalf("%v", err) 322 | } 323 | s.Logf("Stopped serving todo list at https://%s", l.Addr()) 324 | }(tls.NewListener(s.httpsServerL, httpsServer.TLSConfig)) 325 | } 326 | 327 | wg.Wait() 328 | return nil 329 | } 330 | 331 | // Listen creates the listeners for the server 332 | func (s *Server) Listen() error { 333 | if s.hasListeners { // already done this 334 | return nil 335 | } 336 | 337 | if s.hasScheme(schemeHTTPS) { 338 | // Use http host if https host wasn't defined 339 | if s.TLSHost == "" { 340 | s.TLSHost = s.Host 341 | } 342 | // Use http listen limit if https listen limit wasn't defined 343 | if s.TLSListenLimit == 0 { 344 | s.TLSListenLimit = s.ListenLimit 345 | } 346 | // Use http tcp keep alive if https tcp keep alive wasn't defined 347 | if int64(s.TLSKeepAlive) == 0 { 348 | s.TLSKeepAlive = s.KeepAlive 349 | } 350 | // Use http read timeout if https read timeout wasn't defined 351 | if int64(s.TLSReadTimeout) == 0 { 352 | s.TLSReadTimeout = s.ReadTimeout 353 | } 354 | // Use http write timeout if https write timeout wasn't defined 355 | if int64(s.TLSWriteTimeout) == 0 { 356 | s.TLSWriteTimeout = s.WriteTimeout 357 | } 358 | } 359 | 360 | if s.hasScheme(schemeUnix) { 361 | domSockListener, err := net.Listen("unix", string(s.SocketPath)) 362 | if err != nil { 363 | return err 364 | } 365 | s.domainSocketL = domSockListener 366 | } 367 | 368 | if s.hasScheme(schemeHTTP) { 369 | listener, err := net.Listen("tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port))) 370 | if err != nil { 371 | return err 372 | } 373 | 374 | h, p, err := swag.SplitHostPort(listener.Addr().String()) 375 | if err != nil { 376 | return err 377 | } 378 | s.Host = h 379 | s.Port = p 380 | s.httpServerL = listener 381 | } 382 | 383 | if s.hasScheme(schemeHTTPS) { 384 | tlsListener, err := net.Listen("tcp", net.JoinHostPort(s.TLSHost, strconv.Itoa(s.TLSPort))) 385 | if err != nil { 386 | return err 387 | } 388 | 389 | sh, sp, err := swag.SplitHostPort(tlsListener.Addr().String()) 390 | if err != nil { 391 | return err 392 | } 393 | s.TLSHost = sh 394 | s.TLSPort = sp 395 | s.httpsServerL = tlsListener 396 | } 397 | 398 | s.hasListeners = true 399 | return nil 400 | } 401 | 402 | // Shutdown server and clean up resources 403 | func (s *Server) Shutdown() error { 404 | if atomic.CompareAndSwapInt32(&s.shuttingDown, 0, 1) { 405 | close(s.shutdown) 406 | } 407 | return nil 408 | } 409 | 410 | func (s *Server) handleShutdown(wg *sync.WaitGroup, serversPtr *[]*http.Server) { 411 | // wg.Done must occur last, after s.api.ServerShutdown() 412 | // (to preserve old behaviour) 413 | defer wg.Done() 414 | 415 | <-s.shutdown 416 | 417 | servers := *serversPtr 418 | 419 | ctx, cancel := context.WithTimeout(context.TODO(), s.GracefulTimeout) 420 | defer cancel() 421 | 422 | shutdownChan := make(chan bool) 423 | for i := range servers { 424 | server := servers[i] 425 | go func() { 426 | var success bool 427 | defer func() { 428 | shutdownChan <- success 429 | }() 430 | if err := server.Shutdown(ctx); err != nil { 431 | // Error from closing listeners, or context timeout: 432 | s.Logf("HTTP server Shutdown: %v", err) 433 | } else { 434 | success = true 435 | } 436 | }() 437 | } 438 | 439 | // Wait until all listeners have successfully shut down before calling ServerShutdown 440 | success := true 441 | for range servers { 442 | success = success && <-shutdownChan 443 | } 444 | if success { 445 | s.api.ServerShutdown() 446 | } 447 | } 448 | 449 | // GetHandler returns a handler useful for testing 450 | func (s *Server) GetHandler() http.Handler { 451 | return s.handler 452 | } 453 | 454 | // SetHandler allows for setting a http handler on this server 455 | func (s *Server) SetHandler(handler http.Handler) { 456 | s.handler = handler 457 | } 458 | 459 | // UnixListener returns the domain socket listener 460 | func (s *Server) UnixListener() (net.Listener, error) { 461 | if !s.hasListeners { 462 | if err := s.Listen(); err != nil { 463 | return nil, err 464 | } 465 | } 466 | return s.domainSocketL, nil 467 | } 468 | 469 | // HTTPListener returns the http listener 470 | func (s *Server) HTTPListener() (net.Listener, error) { 471 | if !s.hasListeners { 472 | if err := s.Listen(); err != nil { 473 | return nil, err 474 | } 475 | } 476 | return s.httpServerL, nil 477 | } 478 | 479 | // TLSListener returns the https listener 480 | func (s *Server) TLSListener() (net.Listener, error) { 481 | if !s.hasListeners { 482 | if err := s.Listen(); err != nil { 483 | return nil, err 484 | } 485 | } 486 | return s.httpsServerL, nil 487 | } 488 | 489 | func handleInterrupt(once *sync.Once, s *Server) { 490 | once.Do(func() { 491 | for _ = range s.interrupt { 492 | if s.interrupted { 493 | s.Logf("Server already shutting down") 494 | continue 495 | } 496 | s.interrupted = true 497 | s.Logf("Shutting down... ") 498 | if err := s.Shutdown(); err != nil { 499 | s.Logf("HTTP server Shutdown: %v", err) 500 | } 501 | } 502 | }) 503 | } 504 | 505 | func signalNotify(interrupt chan<- os.Signal) { 506 | signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) 507 | } 508 | -------------------------------------------------------------------------------- /swagger.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | description: The product of a tutorial on goswagger.io 4 | title: A To Do list application 5 | version: 1.0.0 6 | consumes: 7 | - application/spkane.todo-list.v1+json 8 | produces: 9 | - application/spkane.todo-list.v1+json 10 | schemes: 11 | - http 12 | paths: 13 | /: 14 | get: 15 | tags: 16 | - todos 17 | operationId: findTodos 18 | parameters: 19 | - name: since 20 | in: query 21 | type: integer 22 | format: int64 23 | - name: limit 24 | in: query 25 | type: integer 26 | format: int32 27 | default: 20 28 | responses: 29 | 200: 30 | description: list the todo operations 31 | schema: 32 | type: array 33 | items: 34 | $ref: "#/definitions/item" 35 | default: 36 | description: generic error response 37 | schema: 38 | $ref: "#/definitions/error" 39 | post: 40 | tags: 41 | - todos 42 | operationId: addOne 43 | parameters: 44 | - name: body 45 | in: body 46 | schema: 47 | $ref: "#/definitions/item" 48 | responses: 49 | 201: 50 | description: Created 51 | schema: 52 | $ref: "#/definitions/item" 53 | default: 54 | description: error 55 | schema: 56 | $ref: "#/definitions/error" 57 | /{id}: 58 | parameters: 59 | - type: integer 60 | format: int64 61 | name: id 62 | in: path 63 | required: true 64 | get: 65 | tags: 66 | - todos 67 | operationId: findTodo 68 | responses: 69 | 200: 70 | description: list the todo 71 | schema: 72 | type: array 73 | items: 74 | $ref: "#/definitions/item" 75 | default: 76 | description: generic error response 77 | schema: 78 | $ref: "#/definitions/error" 79 | put: 80 | tags: 81 | - todos 82 | operationId: updateOne 83 | parameters: 84 | - name: body 85 | in: body 86 | schema: 87 | $ref: "#/definitions/item" 88 | responses: 89 | 200: 90 | description: OK 91 | schema: 92 | $ref: "#/definitions/item" 93 | default: 94 | description: error 95 | schema: 96 | $ref: "#/definitions/error" 97 | delete: 98 | tags: 99 | - todos 100 | operationId: destroyOne 101 | responses: 102 | 204: 103 | description: Deleted 104 | default: 105 | description: error 106 | schema: 107 | $ref: "#/definitions/error" 108 | definitions: 109 | item: 110 | type: object 111 | required: 112 | - description 113 | - completed 114 | properties: 115 | id: 116 | type: integer 117 | format: int64 118 | readOnly: true 119 | description: 120 | type: string 121 | minLength: 1 122 | completed: 123 | type: boolean 124 | error: 125 | type: object 126 | required: 127 | - message 128 | properties: 129 | code: 130 | type: integer 131 | format: int64 132 | message: 133 | type: string 134 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/README.md: -------------------------------------------------------------------------------- 1 | # Terraform + AWS + Todo 2 | 3 | This is some basic Terraform configuration to spin up a simple Todo API server in AWS for teaching purposes. 4 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/backend.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "todo" { 2 | count = "1" 3 | ami = "ami-03a4363a7d864a093" 4 | instance_type = "m5.large" 5 | key_name = aws_key_pair.deployer.key_name 6 | subnet_id = data.terraform_remote_state.training_account.outputs.public_subnets[0] 7 | vpc_security_group_ids = [aws_security_group.instances.id] 8 | associate_public_ip_address = true 9 | connection { 10 | host = self.public_ip 11 | user = "ubuntu" 12 | private_key = file(var.ssh_private_key_path) 13 | } 14 | provisioner "file" { 15 | source = "./files/startup_options.conf" 16 | destination = "/tmp/startup_options.conf" 17 | } 18 | provisioner "file" { 19 | source = "./files/daemon.json" 20 | destination = "/tmp/daemon.json" 21 | } 22 | provisioner "file" { 23 | source = "./files/todo-list.service" 24 | destination = "/tmp/todo-list.service" 25 | } 26 | provisioner "remote-exec" { 27 | inline = [ 28 | "sudo apt-get update", 29 | "sudo apt-get install -y ca-certificates curl gnupg", 30 | "sudo install -m 0755 -d /etc/apt/keyrings", 31 | "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg", 32 | "sudo chmod a+r /etc/apt/keyrings/docker.gpg", 33 | # The following line will need updating with arch or major ubuntu updates 34 | "echo 'deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable' | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null", 35 | "sudo apt-get update", 36 | "sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin", 37 | "sudo usermod -aG docker ubuntu", 38 | "wget https://storage.googleapis.com/gvisor/releases/nightly/latest/runsc", 39 | "chmod +x runsc", 40 | "sudo mv runsc /usr/local/bin", 41 | "sudo cp /tmp/daemon.json /etc/docker/daemon.json", 42 | "sudo cp /tmp/todo-list.service /etc/systemd/system/todo-list.service", 43 | "sudo mkdir -p /etc/systemd/system/docker.service.d/", 44 | "sudo cp /tmp/startup_options.conf /etc/systemd/system/docker.service.d/startup_options.conf", 45 | "sudo systemctl daemon-reload", 46 | "sudo systemctl enable todo-list", 47 | "sudo service docker restart", 48 | "sudo systemctl start todo-list", 49 | ] 50 | } 51 | tags = { 52 | Name = "terraform-${count.index}-spkane" 53 | Trainer = "Sean P. Kane" 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/bin/ip_vars.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then 4 | echo "The script ${BASH_SOURCE[0]} is being sourced..." 5 | echo 6 | else 7 | echo "You must source this bash script, not run it directly." 8 | echo 9 | exit 1 10 | fi 11 | 12 | export todo=$(terraform output | grep todo_ips | cut -d " " -f 3) 13 | num=0 14 | for i in $(echo $todo | sed "s/,/ /g") 15 | do 16 | all_todo_ips[${num}]=${i} 17 | echo "\${all_todo_ips[${num}]}: ${all_todo_ips[${num}]}" 18 | let num+=1 19 | done 20 | export todo_ip=(${all_todo_ips[0]}) 21 | echo "\${todo_ip}: ${todo_ip}" 22 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/bin/local-ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | #ifconfig.me returns the ipv4 address instead of an ipv6 address 6 | echo "{\"public_ip\":\"$(curl -sL4 ifconfig.me)\"}" 7 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/data.tf: -------------------------------------------------------------------------------- 1 | data "external" "public_ip" { 2 | program = ["./bin/local-ip.sh"] 3 | } 4 | 5 | data "terraform_remote_state" "training_account" { 6 | backend = "s3" 7 | config = { 8 | profile = "spkane-training" 9 | bucket = "spkane-training-tfstate" 10 | key = "core/training-account.tfstate" 11 | region = "us-east-1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/files/daemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "default-runtime": "runc", 3 | "runtimes": { 4 | "runsc": { 5 | "path": "/usr/local/bin/runsc" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/files/startup_options.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStart= 3 | ExecStart=/usr/bin/dockerd -H fd:// 4 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/files/todo-list.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Todo List Server Container 3 | Requires=docker.service 4 | After=docker.service 5 | 6 | [Service] 7 | Restart=always 8 | ExecStartPre-=/usr/bin/docker rm -f todo-list 9 | ExecStart=/usr/bin/docker run \ 10 | --name todo-list \ 11 | -p 8080:80 \ 12 | spkane/todo-list-server:latest 13 | ExecStop=/usr/bin/docker stop -t 2 todo-list 14 | ExecStopPost=/usr/bin/docker rm -f todo-list 15 | 16 | [Install] 17 | WantedBy=local.target 18 | -------------------------------------------------------------------------------- /terraform-infrastructure-aws/frontend.tf: -------------------------------------------------------------------------------- 1 | resource "aws_s3_bucket" "lb_logs" { 2 | bucket = "todo-lb-logs" 3 | force_destroy = true 4 | 5 | lifecycle { 6 | prevent_destroy = false 7 | } 8 | 9 | tags = { 10 | purpose = "lb-logs" 11 | environment = "todo" 12 | Trainer = "Sean P. Kane" 13 | } 14 | } 15 | 16 | resource "aws_s3_bucket_versioning" "lb_logs" { 17 | bucket = aws_s3_bucket.lb_logs.id 18 | versioning_configuration { 19 | status = "Enabled" 20 | } 21 | } 22 | 23 | resource "aws_s3_bucket_ownership_controls" "lb_logs" { 24 | bucket = aws_s3_bucket.lb_logs.id 25 | rule { 26 | object_ownership = "BucketOwnerPreferred" 27 | } 28 | } 29 | 30 | resource "aws_s3_bucket_acl" "lb_logs" { 31 | depends_on = [aws_s3_bucket_ownership_controls.lb_logs] 32 | bucket = aws_s3_bucket.lb_logs.id 33 | acl = "private" 34 | } 35 | 36 | resource "aws_s3_bucket_policy" "lb_logs" { 37 | bucket = aws_s3_bucket.lb_logs.id 38 | 39 | policy = <