From 9ed5c01466d6c0ee2955a6918466ca47653ef62c Mon Sep 17 00:00:00 2001 From: Angie Date: Thu, 21 Mar 2024 19:27:33 -0700 Subject: [PATCH] liblab SDK update (#29) Replace speakeasy code with code generated by liblab --- .github/dependabot.yml | 12 + .github/workflows/generate.yml | 28 - .github/workflows/publish-provider.yml | 107 ++ .github/workflows/pull-request-checks.yml | 59 + .github/workflows/release.yaml | 46 - .golangci.yaml | 9 - .goreleaser.yaml => .goreleaser.yml | 65 +- .manifest.json | 173 +++ GNUmakefile | 11 + LICENSE | 2 +- README.md | 147 ++- RELEASES.md | 85 -- USAGE.md | 16 - docs/index.md | 108 +- docs/resources/demo.md | 35 +- docs/resources/grant_kit.md | 242 ++-- docs/resources/identity.md | 36 +- examples/README.md | 1 - .../provider-install-verification/main.tf | 43 - examples/provider/main.tf | 16 + examples/provider/provider.tf | 13 - examples/resources/abbey_demo/resource.tf | 4 - .../resources/abbey_grant_kit/resource.tf | 36 - examples/resources/abbey_identity/resource.tf | 9 - examples/resources/demo/main.tf | 6 + examples/resources/grantkit/main.tf | 46 + examples/resources/identity/main.tf | 8 + files.gen | 156 --- gen.yaml | 13 - go.mod | 126 +- go.sum | 215 ++-- internal/client/.gitignore | 10 + internal/client/README.md | 65 + internal/client/cmd/examples/example.go | 21 + internal/client/go.mod | 3 + .../client/internal/clients/rest/client.go | 37 + .../rest/handlers/bearer_token_handler.go | 38 + .../rest/handlers/default_headers_handler.go | 43 + .../clients/rest/handlers/handler_chain.go | 36 + .../clients/rest/handlers/hook_handler.go | 65 + .../handlers/request_validation_handler.go | 41 + .../handlers/response_validation_handler.go | 41 + .../clients/rest/handlers/retry_handler.go | 53 + .../rest/handlers/terminating_handler.go | 48 + .../rest/handlers/unmarshal_handler.go | 45 + .../clients/rest/hooks/default_hook.go | 19 + .../internal/clients/rest/hooks/hook.go | 46 + .../rest/httptransport/error_response.go | 45 + .../clients/rest/httptransport/request.go | 240 ++++ .../clients/rest/httptransport/response.go | 78 ++ .../internal/configmanager/config_manager.go | 54 + .../internal/marshal/from_complex_object.go | 22 + .../internal/unmarshal/to_complex_object.go | 276 ++++ .../client/internal/unmarshal/to_object.go | 13 + .../client/internal/unmarshal/to_primitive.go | 44 + .../client/internal/unmarshal/unmarshal.go | 63 + internal/client/internal/utils/utils.go | 36 + .../internal/validation/validate_required.go | 24 + .../client/internal/validation/validation.go | 80 ++ internal/client/pkg/client/client.go | 36 + internal/client/pkg/clientconfig/config.go | 23 + internal/client/pkg/demo/demo.go | 52 + internal/client/pkg/demo/demo_params.go | 34 + internal/client/pkg/demo/demo_service.go | 88 ++ internal/client/pkg/demo/request_params.go | 9 + internal/client/pkg/grantkits/grant.go | 112 ++ internal/client/pkg/grantkits/grant_kit.go | 160 +++ .../pkg/grantkits/grant_kit_create_params.go | 64 + .../pkg/grantkits/grant_kit_update_params.go | 65 + .../pkg/grantkits/grant_kits_service.go | 126 ++ .../client/pkg/grantkits/grant_workflow.go | 16 + internal/client/pkg/grantkits/output.go | 40 + internal/client/pkg/grantkits/policy.go | 28 + internal/client/pkg/grantkits/request.go | 148 +++ .../client/pkg/grantkits/request_status.go | 10 + internal/client/pkg/grantkits/review.go | 172 +++ .../client/pkg/grantkits/review_status.go | 10 + internal/client/pkg/grantkits/reviewers.go | 28 + internal/client/pkg/grantkits/step.go | 28 + .../pkg/identities/identities_service.go | 126 ++ internal/client/pkg/identities/identity.go | 77 ++ .../client/pkg/identities/identity_params.go | 41 + internal/client/pkg/shared/client_error.go | 31 + internal/client/pkg/shared/client_response.go | 25 + .../boolplanmodifier/suppress_diff.go | 47 - .../float64planmodifier/suppress_diff.go | 47 - .../int64planmodifier/suppress_diff.go | 47 - .../listplanmodifier/suppress_diff.go | 47 - .../mapplanmodifier/suppress_diff.go | 47 - .../numberplanmodifier/suppress_diff.go | 47 - .../objectplanmodifier/suppress_diff.go | 47 - .../setplanmodifier/suppress_diff.go | 47 - .../stringplanmodifier/suppress_diff.go | 47 - internal/planmodifiers/utils/state_check.go | 25 - .../demo/acceptance/resource_e2e_test.go | 116 ++ internal/provider/demo/resource.go | 234 ++++ internal/provider/demo/resource_test.go | 39 + internal/provider/demo_resource.go | 229 ---- internal/provider/demo_resource_sdk.go | 47 - .../grantkit/acceptance/resource_e2e_test.go | 174 +++ internal/provider/grantkit/resource.go | 1125 +++++++++++++++++ internal/provider/grantkit/resource_test.go | 39 + internal/provider/grantkit_data_source.go | 408 ------ internal/provider/grantkit_data_source_sdk.go | 160 --- internal/provider/grantkit_resource.go | 537 -------- internal/provider/grantkit_resource_sdk.go | 372 ------ .../identity/acceptance/resource_e2e_test.go | 120 ++ internal/provider/identity/resource.go | 258 ++++ internal/provider/identity/resource_test.go | 39 + internal/provider/identity_data_source.go | 146 --- internal/provider/identity_data_source_sdk.go | 18 - internal/provider/identity_resource.go | 264 ---- internal/provider/identity_resource_sdk.go | 53 - internal/provider/provider.go | 110 +- internal/provider/reflect/diags.go | 115 -- internal/provider/reflect/doc.go | 9 - .../provider/reflect/generic_attr_value.go | 14 - internal/provider/reflect/helpers.go | 98 -- internal/provider/reflect/interfaces.go | 353 ------ internal/provider/reflect/into.go | 216 ---- internal/provider/reflect/map.go | 188 --- internal/provider/reflect/number.go | 374 ------ internal/provider/reflect/options.go | 22 - internal/provider/reflect/outof.go | 94 -- internal/provider/reflect/pointer.go | 126 -- internal/provider/reflect/primitive.go | 111 -- internal/provider/reflect/slice.go | 214 ---- internal/provider/reflect/struct.go | 266 ---- internal/provider/type_grant.go | 17 - internal/provider/type_grant_workflow.go | 7 - internal/provider/type_policy.go | 10 - internal/provider/type_request.go | 20 - internal/provider/type_review.go | 21 - internal/provider/type_reviewers.go | 10 - internal/provider/type_step.go | 8 - internal/provider/utils.go | 81 -- internal/sdk/apikeys.go | 239 ---- internal/sdk/connections.go | 337 ----- internal/sdk/connectionspecs.go | 97 -- internal/sdk/demo.go | 258 ---- internal/sdk/grantkits.go | 487 ------- internal/sdk/grants.go | 249 ---- internal/sdk/identities.go | 329 ----- .../pkg/models/operations/approvereview.go | 24 - .../models/operations/cancelrequestbyid.go | 24 - .../sdk/pkg/models/operations/createapikey.go | 18 - .../pkg/models/operations/createconnection.go | 18 - .../sdk/pkg/models/operations/createdemo.go | 18 - .../pkg/models/operations/creategrantkit.go | 18 - .../pkg/models/operations/createidentity.go | 18 - .../pkg/models/operations/createrequest.go | 18 - .../sdk/pkg/models/operations/deleteapikey.go | 21 - .../sdk/pkg/models/operations/deletedemo.go | 18 - .../pkg/models/operations/deletegrantkit.go | 23 - .../pkg/models/operations/deleteidentity.go | 21 - .../sdk/pkg/models/operations/denyreview.go | 24 - .../sdk/pkg/models/operations/getapikeys.go | 18 - .../pkg/models/operations/getconnection.go | 23 - internal/sdk/pkg/models/operations/getdemo.go | 23 - .../sdk/pkg/models/operations/getgrantbyid.go | 23 - .../pkg/models/operations/getgrantkitbyid.go | 23 - .../sdk/pkg/models/operations/getidentity.go | 23 - .../pkg/models/operations/getrequestbyid.go | 23 - .../pkg/models/operations/getreviewbyid.go | 23 - .../pkg/models/operations/listconnections.go | 18 - .../models/operations/listconnectionspecs.go | 18 - .../pkg/models/operations/listgrantkits.go | 18 - .../operations/listgrantkitversionsbyid.go | 23 - .../sdk/pkg/models/operations/listgrants.go | 18 - .../sdk/pkg/models/operations/listrequests.go | 18 - .../sdk/pkg/models/operations/listreviews.go | 18 - .../sdk/pkg/models/operations/revokegrant.go | 23 - .../pkg/models/operations/updateconnection.go | 24 - .../pkg/models/operations/updategrantkit.go | 24 - .../pkg/models/operations/updateidentity.go | 24 - internal/sdk/pkg/models/shared/apikey.go | 16 - internal/sdk/pkg/models/shared/apikeys.go | 8 - .../pkg/models/shared/apikeyscreateparams.go | 12 - internal/sdk/pkg/models/shared/connection.go | 15 - .../sdk/pkg/models/shared/connectionauth.go | 69 - .../models/shared/connectionauthtypeenum.go | 32 - .../pkg/models/shared/connectionlisting.go | 10 - .../sdk/pkg/models/shared/connectionparams.go | 96 -- .../models/shared/connectionparamsgithub.go | 7 - .../shared/connectionparamsgithubvariant.go | 9 - .../models/shared/connectionrequestspec.go | 9 - .../sdk/pkg/models/shared/connectionspec.go | 11 - .../models/shared/connectionspeclisting.go | 10 - .../sdk/pkg/models/shared/connectiontype.go | 35 - .../models/shared/connectionupdateparams.go | 8 - internal/sdk/pkg/models/shared/demo.go | 15 - internal/sdk/pkg/models/shared/demoparams.go | 37 - internal/sdk/pkg/models/shared/error.go | 12 - internal/sdk/pkg/models/shared/grant.go | 20 - internal/sdk/pkg/models/shared/grantkit.go | 22 - .../pkg/models/shared/grantkitcreateparams.go | 11 - .../pkg/models/shared/grantkitupdateparams.go | 12 - .../sdk/pkg/models/shared/grantkitversion.go | 20 - .../sdk/pkg/models/shared/grantworkflow.go | 7 - internal/sdk/pkg/models/shared/httpmethod.go | 35 - internal/sdk/pkg/models/shared/identity.go | 18 - .../sdk/pkg/models/shared/identityparams.go | 10 - .../sdk/pkg/models/shared/keyvaluepair.go | 10 - internal/sdk/pkg/models/shared/oauth2flow.go | 14 - .../pkg/models/shared/oauth2flowexchange.go | 9 - .../sdk/pkg/models/shared/oauth2flowpkce.go | 8 - internal/sdk/pkg/models/shared/output.go | 9 - .../pkg/models/shared/pagerdutyconnection.go | 11 - .../models/shared/pagerdutyconnectionvalue.go | 9 - internal/sdk/pkg/models/shared/pkcemethod.go | 32 - internal/sdk/pkg/models/shared/policy.go | 8 - internal/sdk/pkg/models/shared/request.go | 23 - .../pkg/models/shared/requestcancelparams.go | 8 - .../pkg/models/shared/requestcontenttype.go | 35 - .../sdk/pkg/models/shared/requestparams.go | 8 - internal/sdk/pkg/models/shared/requestspec.go | 12 - .../sdk/pkg/models/shared/requeststatus.go | 41 - internal/sdk/pkg/models/shared/review.go | 24 - internal/sdk/pkg/models/shared/reviewers.go | 8 - .../sdk/pkg/models/shared/reviewstatus.go | 41 - .../pkg/models/shared/reviewupdateparams.go | 7 - internal/sdk/pkg/models/shared/security.go | 7 - internal/sdk/pkg/models/shared/step.go | 8 - internal/sdk/pkg/types/bigint.go | 48 - internal/sdk/pkg/types/date.go | 86 -- internal/sdk/pkg/types/datetime.go | 23 - internal/sdk/pkg/utils/contenttype.go | 33 - internal/sdk/pkg/utils/form.go | 114 -- internal/sdk/pkg/utils/headers.go | 100 -- internal/sdk/pkg/utils/pathparams.go | 126 -- internal/sdk/pkg/utils/queryparams.go | 178 --- internal/sdk/pkg/utils/requestbody.go | 373 ------ internal/sdk/pkg/utils/retries.go | 117 -- internal/sdk/pkg/utils/security.go | 292 ----- internal/sdk/pkg/utils/utils.go | 152 --- internal/sdk/requests.go | 342 ----- internal/sdk/reviews.go | 343 ----- internal/sdk/sdk.go | 219 ---- internal/shared/models/grant/grant.go | 17 + .../models/grant_workflow/grant_workflow.go | 9 + .../models/output/output.go} | 10 +- .../shared/models/permission/permission.go | 4 + internal/shared/models/policy/policy.go | 10 + internal/shared/models/request/request.go | 21 + .../models/request_status/request_status.go | 4 + internal/shared/models/review/review.go | 23 + .../models/review_status/review_status.go | 4 + internal/shared/models/reviewers/reviewers.go | 10 + internal/shared/models/step/step.go | 11 + internal/tools/tools.go | 7 - internal/utils/utils.go | 181 +++ internal/validators/DateValidator.go | 50 - internal/validators/ExactlyOneChild.go | 53 - internal/validators/JSONParseValidator.go | 51 - internal/validators/RFC3339Validator.go | 50 - main.go | 12 +- templates/index.md.tmpl | 63 - terraform-registry-manifest.json | 8 +- tools/tools.go | 2 - validator/rfc3986.go | 45 - 260 files changed, 6541 insertions(+), 12530 deletions(-) create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/generate.yml create mode 100644 .github/workflows/publish-provider.yml create mode 100644 .github/workflows/pull-request-checks.yml delete mode 100644 .github/workflows/release.yaml delete mode 100644 .golangci.yaml rename .goreleaser.yaml => .goreleaser.yml (51%) create mode 100644 .manifest.json create mode 100644 GNUmakefile delete mode 100644 RELEASES.md delete mode 100755 USAGE.md delete mode 100755 examples/README.md delete mode 100644 examples/provider-install-verification/main.tf create mode 100644 examples/provider/main.tf delete mode 100755 examples/provider/provider.tf delete mode 100755 examples/resources/abbey_demo/resource.tf delete mode 100755 examples/resources/abbey_grant_kit/resource.tf delete mode 100755 examples/resources/abbey_identity/resource.tf create mode 100644 examples/resources/demo/main.tf create mode 100644 examples/resources/grantkit/main.tf create mode 100644 examples/resources/identity/main.tf delete mode 100755 files.gen delete mode 100755 gen.yaml mode change 100755 => 100644 go.mod mode change 100755 => 100644 go.sum create mode 100644 internal/client/.gitignore create mode 100644 internal/client/README.md create mode 100644 internal/client/cmd/examples/example.go create mode 100644 internal/client/go.mod create mode 100644 internal/client/internal/clients/rest/client.go create mode 100644 internal/client/internal/clients/rest/handlers/bearer_token_handler.go create mode 100644 internal/client/internal/clients/rest/handlers/default_headers_handler.go create mode 100644 internal/client/internal/clients/rest/handlers/handler_chain.go create mode 100644 internal/client/internal/clients/rest/handlers/hook_handler.go create mode 100644 internal/client/internal/clients/rest/handlers/request_validation_handler.go create mode 100644 internal/client/internal/clients/rest/handlers/response_validation_handler.go create mode 100644 internal/client/internal/clients/rest/handlers/retry_handler.go create mode 100644 internal/client/internal/clients/rest/handlers/terminating_handler.go create mode 100644 internal/client/internal/clients/rest/handlers/unmarshal_handler.go create mode 100644 internal/client/internal/clients/rest/hooks/default_hook.go create mode 100644 internal/client/internal/clients/rest/hooks/hook.go create mode 100644 internal/client/internal/clients/rest/httptransport/error_response.go create mode 100644 internal/client/internal/clients/rest/httptransport/request.go create mode 100644 internal/client/internal/clients/rest/httptransport/response.go create mode 100644 internal/client/internal/configmanager/config_manager.go create mode 100644 internal/client/internal/marshal/from_complex_object.go create mode 100644 internal/client/internal/unmarshal/to_complex_object.go create mode 100644 internal/client/internal/unmarshal/to_object.go create mode 100644 internal/client/internal/unmarshal/to_primitive.go create mode 100644 internal/client/internal/unmarshal/unmarshal.go create mode 100644 internal/client/internal/utils/utils.go create mode 100644 internal/client/internal/validation/validate_required.go create mode 100644 internal/client/internal/validation/validation.go create mode 100644 internal/client/pkg/client/client.go create mode 100644 internal/client/pkg/clientconfig/config.go create mode 100644 internal/client/pkg/demo/demo.go create mode 100644 internal/client/pkg/demo/demo_params.go create mode 100644 internal/client/pkg/demo/demo_service.go create mode 100644 internal/client/pkg/demo/request_params.go create mode 100644 internal/client/pkg/grantkits/grant.go create mode 100644 internal/client/pkg/grantkits/grant_kit.go create mode 100644 internal/client/pkg/grantkits/grant_kit_create_params.go create mode 100644 internal/client/pkg/grantkits/grant_kit_update_params.go create mode 100644 internal/client/pkg/grantkits/grant_kits_service.go create mode 100644 internal/client/pkg/grantkits/grant_workflow.go create mode 100644 internal/client/pkg/grantkits/output.go create mode 100644 internal/client/pkg/grantkits/policy.go create mode 100644 internal/client/pkg/grantkits/request.go create mode 100644 internal/client/pkg/grantkits/request_status.go create mode 100644 internal/client/pkg/grantkits/review.go create mode 100644 internal/client/pkg/grantkits/review_status.go create mode 100644 internal/client/pkg/grantkits/reviewers.go create mode 100644 internal/client/pkg/grantkits/step.go create mode 100644 internal/client/pkg/identities/identities_service.go create mode 100644 internal/client/pkg/identities/identity.go create mode 100644 internal/client/pkg/identities/identity_params.go create mode 100644 internal/client/pkg/shared/client_error.go create mode 100644 internal/client/pkg/shared/client_response.go delete mode 100755 internal/planmodifiers/boolplanmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/float64planmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/int64planmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/listplanmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/mapplanmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/numberplanmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/objectplanmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/setplanmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/stringplanmodifier/suppress_diff.go delete mode 100755 internal/planmodifiers/utils/state_check.go create mode 100644 internal/provider/demo/acceptance/resource_e2e_test.go create mode 100644 internal/provider/demo/resource.go create mode 100644 internal/provider/demo/resource_test.go delete mode 100755 internal/provider/demo_resource.go delete mode 100755 internal/provider/demo_resource_sdk.go create mode 100644 internal/provider/grantkit/acceptance/resource_e2e_test.go create mode 100644 internal/provider/grantkit/resource.go create mode 100644 internal/provider/grantkit/resource_test.go delete mode 100755 internal/provider/grantkit_data_source.go delete mode 100755 internal/provider/grantkit_data_source_sdk.go delete mode 100755 internal/provider/grantkit_resource.go delete mode 100755 internal/provider/grantkit_resource_sdk.go create mode 100644 internal/provider/identity/acceptance/resource_e2e_test.go create mode 100644 internal/provider/identity/resource.go create mode 100644 internal/provider/identity/resource_test.go delete mode 100755 internal/provider/identity_data_source.go delete mode 100755 internal/provider/identity_data_source_sdk.go delete mode 100755 internal/provider/identity_resource.go delete mode 100755 internal/provider/identity_resource_sdk.go mode change 100755 => 100644 internal/provider/provider.go delete mode 100755 internal/provider/reflect/diags.go delete mode 100755 internal/provider/reflect/doc.go delete mode 100755 internal/provider/reflect/generic_attr_value.go delete mode 100755 internal/provider/reflect/helpers.go delete mode 100755 internal/provider/reflect/interfaces.go delete mode 100755 internal/provider/reflect/into.go delete mode 100755 internal/provider/reflect/map.go delete mode 100755 internal/provider/reflect/number.go delete mode 100755 internal/provider/reflect/options.go delete mode 100755 internal/provider/reflect/outof.go delete mode 100755 internal/provider/reflect/pointer.go delete mode 100755 internal/provider/reflect/primitive.go delete mode 100755 internal/provider/reflect/slice.go delete mode 100755 internal/provider/reflect/struct.go delete mode 100755 internal/provider/type_grant.go delete mode 100755 internal/provider/type_grant_workflow.go delete mode 100755 internal/provider/type_policy.go delete mode 100755 internal/provider/type_request.go delete mode 100755 internal/provider/type_review.go delete mode 100755 internal/provider/type_reviewers.go delete mode 100755 internal/provider/type_step.go delete mode 100755 internal/provider/utils.go delete mode 100755 internal/sdk/apikeys.go delete mode 100755 internal/sdk/connections.go delete mode 100755 internal/sdk/connectionspecs.go delete mode 100755 internal/sdk/demo.go delete mode 100755 internal/sdk/grantkits.go delete mode 100755 internal/sdk/grants.go delete mode 100755 internal/sdk/identities.go delete mode 100755 internal/sdk/pkg/models/operations/approvereview.go delete mode 100755 internal/sdk/pkg/models/operations/cancelrequestbyid.go delete mode 100755 internal/sdk/pkg/models/operations/createapikey.go delete mode 100755 internal/sdk/pkg/models/operations/createconnection.go delete mode 100755 internal/sdk/pkg/models/operations/createdemo.go delete mode 100755 internal/sdk/pkg/models/operations/creategrantkit.go delete mode 100755 internal/sdk/pkg/models/operations/createidentity.go delete mode 100755 internal/sdk/pkg/models/operations/createrequest.go delete mode 100755 internal/sdk/pkg/models/operations/deleteapikey.go delete mode 100755 internal/sdk/pkg/models/operations/deletedemo.go delete mode 100755 internal/sdk/pkg/models/operations/deletegrantkit.go delete mode 100755 internal/sdk/pkg/models/operations/deleteidentity.go delete mode 100755 internal/sdk/pkg/models/operations/denyreview.go delete mode 100755 internal/sdk/pkg/models/operations/getapikeys.go delete mode 100755 internal/sdk/pkg/models/operations/getconnection.go delete mode 100755 internal/sdk/pkg/models/operations/getdemo.go delete mode 100755 internal/sdk/pkg/models/operations/getgrantbyid.go delete mode 100755 internal/sdk/pkg/models/operations/getgrantkitbyid.go delete mode 100755 internal/sdk/pkg/models/operations/getidentity.go delete mode 100755 internal/sdk/pkg/models/operations/getrequestbyid.go delete mode 100755 internal/sdk/pkg/models/operations/getreviewbyid.go delete mode 100755 internal/sdk/pkg/models/operations/listconnections.go delete mode 100755 internal/sdk/pkg/models/operations/listconnectionspecs.go delete mode 100755 internal/sdk/pkg/models/operations/listgrantkits.go delete mode 100755 internal/sdk/pkg/models/operations/listgrantkitversionsbyid.go delete mode 100755 internal/sdk/pkg/models/operations/listgrants.go delete mode 100755 internal/sdk/pkg/models/operations/listrequests.go delete mode 100755 internal/sdk/pkg/models/operations/listreviews.go delete mode 100755 internal/sdk/pkg/models/operations/revokegrant.go delete mode 100755 internal/sdk/pkg/models/operations/updateconnection.go delete mode 100755 internal/sdk/pkg/models/operations/updategrantkit.go delete mode 100755 internal/sdk/pkg/models/operations/updateidentity.go delete mode 100755 internal/sdk/pkg/models/shared/apikey.go delete mode 100755 internal/sdk/pkg/models/shared/apikeys.go delete mode 100755 internal/sdk/pkg/models/shared/apikeyscreateparams.go delete mode 100755 internal/sdk/pkg/models/shared/connection.go delete mode 100755 internal/sdk/pkg/models/shared/connectionauth.go delete mode 100755 internal/sdk/pkg/models/shared/connectionauthtypeenum.go delete mode 100755 internal/sdk/pkg/models/shared/connectionlisting.go delete mode 100755 internal/sdk/pkg/models/shared/connectionparams.go delete mode 100755 internal/sdk/pkg/models/shared/connectionparamsgithub.go delete mode 100755 internal/sdk/pkg/models/shared/connectionparamsgithubvariant.go delete mode 100755 internal/sdk/pkg/models/shared/connectionrequestspec.go delete mode 100755 internal/sdk/pkg/models/shared/connectionspec.go delete mode 100755 internal/sdk/pkg/models/shared/connectionspeclisting.go delete mode 100755 internal/sdk/pkg/models/shared/connectiontype.go delete mode 100755 internal/sdk/pkg/models/shared/connectionupdateparams.go delete mode 100755 internal/sdk/pkg/models/shared/demo.go delete mode 100755 internal/sdk/pkg/models/shared/demoparams.go delete mode 100755 internal/sdk/pkg/models/shared/error.go delete mode 100755 internal/sdk/pkg/models/shared/grant.go delete mode 100755 internal/sdk/pkg/models/shared/grantkit.go delete mode 100755 internal/sdk/pkg/models/shared/grantkitcreateparams.go delete mode 100755 internal/sdk/pkg/models/shared/grantkitupdateparams.go delete mode 100755 internal/sdk/pkg/models/shared/grantkitversion.go delete mode 100755 internal/sdk/pkg/models/shared/grantworkflow.go delete mode 100755 internal/sdk/pkg/models/shared/httpmethod.go delete mode 100755 internal/sdk/pkg/models/shared/identity.go delete mode 100755 internal/sdk/pkg/models/shared/identityparams.go delete mode 100755 internal/sdk/pkg/models/shared/keyvaluepair.go delete mode 100755 internal/sdk/pkg/models/shared/oauth2flow.go delete mode 100755 internal/sdk/pkg/models/shared/oauth2flowexchange.go delete mode 100755 internal/sdk/pkg/models/shared/oauth2flowpkce.go delete mode 100755 internal/sdk/pkg/models/shared/output.go delete mode 100755 internal/sdk/pkg/models/shared/pagerdutyconnection.go delete mode 100755 internal/sdk/pkg/models/shared/pagerdutyconnectionvalue.go delete mode 100755 internal/sdk/pkg/models/shared/pkcemethod.go delete mode 100755 internal/sdk/pkg/models/shared/policy.go delete mode 100755 internal/sdk/pkg/models/shared/request.go delete mode 100755 internal/sdk/pkg/models/shared/requestcancelparams.go delete mode 100755 internal/sdk/pkg/models/shared/requestcontenttype.go delete mode 100755 internal/sdk/pkg/models/shared/requestparams.go delete mode 100755 internal/sdk/pkg/models/shared/requestspec.go delete mode 100755 internal/sdk/pkg/models/shared/requeststatus.go delete mode 100755 internal/sdk/pkg/models/shared/review.go delete mode 100755 internal/sdk/pkg/models/shared/reviewers.go delete mode 100755 internal/sdk/pkg/models/shared/reviewstatus.go delete mode 100755 internal/sdk/pkg/models/shared/reviewupdateparams.go delete mode 100755 internal/sdk/pkg/models/shared/security.go delete mode 100755 internal/sdk/pkg/models/shared/step.go delete mode 100755 internal/sdk/pkg/types/bigint.go delete mode 100755 internal/sdk/pkg/types/date.go delete mode 100755 internal/sdk/pkg/types/datetime.go delete mode 100755 internal/sdk/pkg/utils/contenttype.go delete mode 100755 internal/sdk/pkg/utils/form.go delete mode 100755 internal/sdk/pkg/utils/headers.go delete mode 100755 internal/sdk/pkg/utils/pathparams.go delete mode 100755 internal/sdk/pkg/utils/queryparams.go delete mode 100755 internal/sdk/pkg/utils/requestbody.go delete mode 100755 internal/sdk/pkg/utils/retries.go delete mode 100755 internal/sdk/pkg/utils/security.go delete mode 100755 internal/sdk/pkg/utils/utils.go delete mode 100755 internal/sdk/requests.go delete mode 100755 internal/sdk/reviews.go delete mode 100755 internal/sdk/sdk.go create mode 100644 internal/shared/models/grant/grant.go create mode 100644 internal/shared/models/grant_workflow/grant_workflow.go rename internal/{provider/type_output.go => shared/models/output/output.go} (50%) mode change 100755 => 100644 create mode 100644 internal/shared/models/permission/permission.go create mode 100644 internal/shared/models/policy/policy.go create mode 100644 internal/shared/models/request/request.go create mode 100644 internal/shared/models/request_status/request_status.go create mode 100644 internal/shared/models/review/review.go create mode 100644 internal/shared/models/review_status/review_status.go create mode 100644 internal/shared/models/reviewers/reviewers.go create mode 100644 internal/shared/models/step/step.go delete mode 100644 internal/tools/tools.go create mode 100644 internal/utils/utils.go delete mode 100755 internal/validators/DateValidator.go delete mode 100755 internal/validators/ExactlyOneChild.go delete mode 100755 internal/validators/JSONParseValidator.go delete mode 100755 internal/validators/RFC3339Validator.go mode change 100755 => 100644 main.go delete mode 100644 templates/index.md.tmpl mode change 100755 => 100644 terraform-registry-manifest.json mode change 100755 => 100644 tools/tools.go delete mode 100644 validator/rfc3986.go diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2c40b3a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: 'gomod' # See documentation for possible values + directory: '/' # Location of package manifests + open-pull-requests-limit: 25 + schedule: + interval: 'daily' + - package-ecosystem: 'github-actions' # See documentation for possible values + directory: '/' # Location of package manifests + open-pull-requests-limit: 25 + schedule: + interval: 'daily' diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml deleted file mode 100644 index f53e900..0000000 --- a/.github/workflows/generate.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Generate - -on: - workflow_dispatch: # Allows manual triggering of the workflow to generate SDK - inputs: - force: - description: "Force generation of SDKs on main branch" - type: boolean - default: false - schedule: - - cron: 0 0 * * * # Runs every day at midnight -jobs: - generate: - uses: speakeasy-api/sdk-generation-action/.github/workflows/sdk-generation.yaml@v14 - with: - speakeasy_version: latest - openapi_doc_auth_header: Authorization - openapi_docs: | - - https://raw.githubusercontent.com/abbeylabs/edge/main/api/openapi.yaml - languages: | - - terraform - create_release: true - force: ${{ github.event.inputs.force }} - mode: pr - secrets: - github_access_token: ${{ secrets.GITHUB_TOKEN }} - speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }} - openapi_doc_auth_token: ${{ secrets.EDGE_SPEC_TOKEN }} diff --git a/.github/workflows/publish-provider.yml b/.github/workflows/publish-provider.yml new file mode 100644 index 0000000..63daaef --- /dev/null +++ b/.github/workflows/publish-provider.yml @@ -0,0 +1,107 @@ +name: Publish Provider + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +permissions: + contents: write + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: '1.19' + stable: true + + - name: Cache Go Modules + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Tidy Modules + run: go mod tidy + + - name: Build the provider + run: go build -o terraform-provider-abbey + + - name: Run Unit Tests + run: make unit-test + + # Uncomment once you have acceptance tests set up and you want them to run on PR checks + # - name: Run Acceptance Tests + # run: make acceptance-test + + release: + needs: build-and-test + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: '1.19' + stable: true + + # Import the GPG key before the build step that requires it + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + id: import_gpg + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.PASSPHRASE }} + env: + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref_name }} + release_name: Release ${{ github.ref_name }} + draft: false + prerelease: false + + publish: + needs: release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + # Allow goreleaser to access older tag information. + fetch-depth: 0 + - uses: actions/setup-go@v2 + with: + go-version-file: 'go.mod' + cache: true + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + id: import_gpg + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.PASSPHRASE }} + env: + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + args: release --clean + env: + # GitHub sets the GITHUB_TOKEN secret automatically. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} diff --git a/.github/workflows/pull-request-checks.yml b/.github/workflows/pull-request-checks.yml new file mode 100644 index 0000000..9411c0d --- /dev/null +++ b/.github/workflows/pull-request-checks.yml @@ -0,0 +1,59 @@ +name: Pull Request Checks + +on: + pull_request: + +permissions: + pull-requests: write + contents: write + +jobs: + linting-and-testing: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: '1.19' + stable: true + + - name: Cache Go Modules + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Tidy Modules + run: go mod tidy + + - name: Build the provider + run: go build -o terraform-provider-abbey . + + - name: Generate Docs + run: go generate ./... + + - name: Run Unit Tests + run: make unit-test + + dependabot: + name: 'Dependabot' + needs: [linting-and-testing] + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}} + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v1.6.0 + with: + github-token: '${{ secrets.GITHUB_TOKEN }}' + - name: Enable auto-merge for Dependabot PRs + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index c336ade..0000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# This GitHub action can publish assets for release when a tag is created. -# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). -# -# This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your -# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` -# secret. If you would rather own your own GPG handling, please fork this action -# or use an alternative one for key handling. -# -# You will need to pass the `--batch` flag to `gpg` in your signing step -# in `goreleaser` to indicate this is being used in a non-interactive mode. -# -name: release -on: - push: - tags: - - 'v*' -permissions: - contents: write -jobs: - goreleaser: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - name: Unshallow - run: git fetch --prune --unshallow - - name: Set up Go - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 - with: - go-version-file: 'go.mod' - cache: true - - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 # v5.2.0 - id: import_gpg - with: - gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.PASSPHRASE }} - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@8f67e590f2d095516493f017008adc464e63adb1 # v4.1.0 - with: - version: latest - args: release --rm-dist - env: - GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} - # GitHub sets this automatically - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.golangci.yaml b/.golangci.yaml deleted file mode 100644 index 2fbb698..0000000 --- a/.golangci.yaml +++ /dev/null @@ -1,9 +0,0 @@ -linters: - enable: - - exhaustruct - -linters-settings: - exhaustruct: - exclude: - - 'terraform-plugin-framework/resource/schema\..+' - - 'terraform-plugin-testing/helper/resource\..+' \ No newline at end of file diff --git a/.goreleaser.yaml b/.goreleaser.yml similarity index 51% rename from .goreleaser.yaml rename to .goreleaser.yml index 23f50b3..2589620 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yml @@ -1,14 +1,17 @@ -# Visit https://goreleaser.com for documentation on how to customize this -# behavior. +# This section defines how the artifacts should be archived +archives: + - format: zip + name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' + +# Set necessary hooks before go releaser executes before: hooks: - # this is just an example and not a requirement for provider building/publishing - go mod tidy + +# Build customization builds: - - env: - # goreleaser does not work with CGO, it could also complicate - # usage by users in CI/CD systems like Terraform Cloud where - # they are unable to install libraries. + - binary: '{{ .ProjectName }}_v{{ .Version }}' + env: - CGO_ENABLED=0 mod_timestamp: '{{ .CommitTimestamp }}' flags: @@ -28,33 +31,37 @@ builds: ignore: - goos: darwin goarch: '386' - binary: '{{ .ProjectName }}_v{{ .Version }}' -archives: - - format: zip - name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' + +# Include a changelog or not +changelog: + skip: true + +# Checksum and signing configuration checksum: + name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' + algorithm: sha256 extra_files: - glob: 'terraform-registry-manifest.json' name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' - name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' - algorithm: sha256 -signs: - - artifacts: checksum - args: - # if you are using this in a GitHub action or some other automated pipeline, you - # need to pass the batch flag to indicate its not interactive. - - "--batch" - - "--local-user" - - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key - - "--output" - - "${signature}" - - "--detach-sign" - - "${artifact}" + +# This section defines how the artifacts should be published release: extra_files: - glob: 'terraform-registry-manifest.json' name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' - # If you want to manually examine the release before its live, uncomment this line: - # draft: true -changelog: - skip: true + +# This section defines how the artifacts should be signed +signs: + - artifacts: checksum + args: + - '--batch' + - '--local-user' + - '{{ .Env.GPG_FINGERPRINT }}' + - '--output' + - '${signature}' + - '--detach-sign' + - '${artifact}' + +# Snapshot configuration in case you want to create non-release builds +snapshot: + name_template: '{{ .Tag }}-snapshot' diff --git a/.manifest.json b/.manifest.json new file mode 100644 index 0000000..64595ee --- /dev/null +++ b/.manifest.json @@ -0,0 +1,173 @@ +{ + "liblabVersion": "2.0.17", + "date": "2024-02-24T01:32:42.131Z", + "config": { + "usesFormData": false, + "authentication": { + "access": { + "prefix": "Bearer" + } + }, + "environmentVariables": [], + "inferServiceNames": false, + "httpLibrary": { + "name": "axios", + "packages": { + "axios": "^1.6.7" + }, + "languages": ["typescript"] + }, + "auth": ["bearer"], + "sdkName": "client", + "sdkVersion": "1.0.0", + "retry": { + "enabled": true, + "maxAttempts": 3, + "retryDelay": 150 + }, + "multiTenant": true, + "customQueries": { + "paths": [], + "rawQueries": [], + "queriesData": [] + }, + "generateEnv": true, + "injectedModels": [], + "license": { + "type": "MIT" + }, + "deliveryMethod": "zip", + "apiId": 485, + "liblabVersion": "1", + "deliveryMethods": ["zip"], + "languages": ["terraform"], + "apiName": "edge-api", + "apiVersion": "1.0.0", + "createDocs": false, + "languageOptions": { + "terraform": { + "hideComputedDiff": false, + "mockAcceptance": true, + "providerGoModuleName": "abbey/v2", + "providerName": "abbey", + "providerVersion": "0.2.7", + "githubRepoName": "terraform-provider-abbey" + } + }, + "publishing": { + "githubOrg": "abbeylabs" + }, + "specFilePath": "api/openapi.yaml", + "validationsToIgnore": [], + "devContainer": false, + "responseHeaders": false, + "specUrl": "https://prod-liblab-api-stack-specs.s3.us-east-1.amazonaws.com/485/open-api-spec.yaml?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA5P3QKKDKGVNIJ2H7%2F20240224%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240224T013236Z&X-Amz-Expires=43200&X-Amz-Signature=67f71a255d03389f57759061c5ab904a9391cf8fa031c0bc8c2a1e73f447b14d&X-Amz-SignedHeaders=host&x-id=GetObject", + "language": "terraform", + "goModuleName": "github.com/go-provider-sdk", + "hooks": { + "enabled": false, + "sourceDir": "" + }, + "planModifiers": { + "resources": { + "enabled": false + }, + "attributes": { + "enabled": false + } + }, + "providerGoModuleName": "abbey/v2", + "providerName": "abbey", + "providerVersion": "0.2.7", + "mockAcceptance": true, + "hideComputedDiff": false + }, + "files": [ + ".github/dependabot.yml", + "examples/provider/main.tf", + "go.mod", + ".goreleaser.yml", + "main.go", + "GNUmakefile", + "internal/shared/models/grant_workflow/grant_workflow.go", + "internal/shared/models/policy/policy.go", + "internal/shared/models/output/output.go", + "internal/shared/models/grant/grant.go", + "internal/shared/models/request/request.go", + "internal/shared/models/step/step.go", + "internal/shared/models/reviewers/reviewers.go", + "internal/shared/models/request_status/request_status.go", + "internal/shared/models/review/review.go", + "internal/shared/models/review_status/review_status.go", + "internal/shared/models/permission/permission.go", + ".github/workflows/pull-request-checks.yml", + "README.md", + ".github/workflows/publish-provider.yml", + "terraform-registry-manifest.json", + "internal/provider/grantkit/resource_test.go", + "internal/provider/identity/resource_test.go", + "internal/provider/demo/resource_test.go", + "tools/tools.go", + "internal/utils/utils.go", + "internal/provider/provider.go", + "examples/resources/demo/main.tf", + "examples/resources/identity/main.tf", + "internal/provider/demo/acceptance/resource_e2e_test.go", + "internal/provider/identity/acceptance/resource_e2e_test.go", + "examples/resources/grantkit/main.tf", + "internal/provider/grantkit/acceptance/resource_e2e_test.go", + "internal/provider/demo/resource.go", + "internal/provider/identity/resource.go", + "internal/provider/grantkit/resource.go", + "internal/client/.gitignore", + "internal/client/cmd/examples/example.go", + "internal/client/go.mod", + "internal/client/internal/clients/rest/client.go", + "internal/client/internal/clients/rest/handlers/bearer_token_handler.go", + "internal/client/internal/clients/rest/handlers/default_headers_handler.go", + "internal/client/internal/clients/rest/handlers/handler_chain.go", + "internal/client/internal/clients/rest/handlers/hook_handler.go", + "internal/client/internal/clients/rest/handlers/request_validation_handler.go", + "internal/client/internal/clients/rest/handlers/retry_handler.go", + "internal/client/internal/clients/rest/handlers/terminating_handler.go", + "internal/client/internal/clients/rest/hooks/default_hook.go", + "internal/client/internal/clients/rest/hooks/hook.go", + "internal/client/internal/clients/rest/httptransport/error_response.go", + "internal/client/internal/clients/rest/httptransport/request.go", + "internal/client/internal/clients/rest/httptransport/response.go", + "internal/client/internal/configmanager/config_manager.go", + "internal/client/internal/marshal/from_complex_object.go", + "internal/client/internal/unmarshal/to_array.go", + "internal/client/internal/unmarshal/to_complex_object.go", + "internal/client/internal/unmarshal/to_object.go", + "internal/client/internal/unmarshal/to_primitive.go", + "internal/client/internal/utils/utils.go", + "internal/client/internal/validation/validate_required.go", + "internal/client/internal/validation/validation.go", + "internal/client/pkg/client/client.go", + "internal/client/pkg/clientconfig/config.go", + "internal/client/pkg/demo/demo_params.go", + "internal/client/pkg/demo/demo_service.go", + "internal/client/pkg/demo/demo.go", + "internal/client/pkg/demo/request_params.go", + "internal/client/pkg/grantkits/grant_kit_create_params.go", + "internal/client/pkg/grantkits/grant_kit_update_params.go", + "internal/client/pkg/grantkits/grant_kit.go", + "internal/client/pkg/grantkits/grant_kits_service.go", + "internal/client/pkg/grantkits/grant_workflow.go", + "internal/client/pkg/grantkits/grant.go", + "internal/client/pkg/grantkits/output.go", + "internal/client/pkg/grantkits/policy.go", + "internal/client/pkg/grantkits/request_status.go", + "internal/client/pkg/grantkits/request.go", + "internal/client/pkg/grantkits/review_status.go", + "internal/client/pkg/grantkits/review.go", + "internal/client/pkg/grantkits/reviewers.go", + "internal/client/pkg/grantkits/step.go", + "internal/client/pkg/identities/identities_service.go", + "internal/client/pkg/identities/identity_params.go", + "internal/client/pkg/identities/identity.go", + "internal/client/pkg/shared/client_response.go", + "internal/client/README.md" + ] +} diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..b3ee3ad --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,11 @@ +.PHONY: test unit-test acceptance-test + +test: unit-test acceptance-test + +unit-test: + @echo "Running unit tests..." + @go test -tags=unit ./... -v $(TESTARGS) -timeout 120m + +acceptance-test: + @echo "Running acceptance tests..." + @go test -tags=acceptance ./... -v $(TESTARGS) -timeout 120m diff --git a/LICENSE b/LICENSE index a612ad9..14e2f77 100644 --- a/LICENSE +++ b/LICENSE @@ -35,7 +35,7 @@ Mozilla Public License Version 2.0 means any form of the work other than Source Code Form. 1.7. "Larger Work" - means a work that combines Covered Software with other material, in + means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" diff --git a/README.md b/README.md index 9658714..d0d1146 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,136 @@ -# Terraform Abbey Provider +# abbey Terraform Provider 0.2.7 -![GitHub release (with filter)](https://img.shields.io/github/v/release/abbeylabs/terraform-provider-abbey) -![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/abbeylabs/terraform-provider-abbey/release.yaml) -![GitHub issues](https://img.shields.io/github/issues/abbeylabs/terraform-provider-abbey) -[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B38958%2Fgit%40github.com%3Aabbeylabs%2Fterraform-provider-abbey.git.svg?type=shield)](https://app.fossa.com/projects/custom%2B38958%2Fgit%40github.com%3Aabbeylabs%2Fterraform-provider-abbey.git?ref=badge_shield) -![GitHub](https://img.shields.io/github/license/abbeylabs/terraform-provider-abbey) +The public Abbey API. Used for integrating with Abbey and building interfaces to extend the Abbey platform. See https://docs.abbey.io for more information. +This repository contains a Terraform provider that allows you to manage resources through the abbey API. +## Prerequisites -The Abbey provider is used by security teams and DevOps/DevSecOps engineers to automate and secure -access to sensitive resources in their existing cloud infrastructure. +- [Go](https://golang.org/doc/install) >= 1.19 -Resources in this provider interact with endpoints from the Abbey API and needs to be -configured with credentials before it can be used. +- [Terraform](https://www.terraform.io/downloads.html) >= 1.0 -## Background +- Access to the abbey API. -Abbey is a platform for security teams and DevOps/DevSecOps engineers to -automate and secure access to sensitive resources. +## Installing The Provider -With Abbey, you can improve your security and compliance programs by automatically controlling -and right-sizing permissions so the risks around unauthorized access is limited in the event of a breach. +1. Clone the repository: -You do this by leveraging your normal Infrastructure as Code (IaC) tooling — -Terraform, CI/CD systems, secrets managers, and Terraform wrappers. -Abbey provides a Terraform plugin and platform that extends your Infrastructure as Code capabilities -from Infrastructure to Identity, Access, and Management (IAM). +```bash +git clone https://github.com/liblaber/terraform-provider-abbey.git +``` -## Contributing +2. Navigate to the directory: -Development happens in the [GitHub repo](https://github.com/abbeylabs/terraform-provider-abbey): +```bash +cd terraform-provider-abbey +``` -- [Releases](https://github.com/abbeylabs/terraform-provider-abbey/releases) -- [Issues](https://github.com/abbeylabs/terraform-provider-abbey/issues) +3. Update module references: -## License +```bash +go mod tidy +``` -This project is licensed under the MPL 2.0 license. See [LICENSE](LICENSE) for more details. +4. Build the provider: +```bash +go build -o terraform-provider-abbey +``` + +5. Move the provider to your plugins directory: + +```bash +mkdir -p ~/.terraform.d/plugins/example.com/user/abbey/0.2.7/ +mv terraform-provider-abbey ~/.terraform.d/plugins/example.com/user/abbey/0.2.7/ +``` + +Note: The directory structure is important. The provider must be located at `~/.terraform.d/plugins/example.com/user/abbey/0.2.7//terraform-provider-abbey` +Also please change `example.com/user` and `` to match your real values. +To get the run `terraform version`, possible values: `linux_amd64`, `darwin_arm64`, `windows_amd64`, etc. + +## Setting Up The Provider + +1. Configure the provider: + +In your Terraform configuration, reference the provider and supply the necessary credentials: + +```hcl +provider "abbey" { +host = "https://localhost/" +api_token = "YOUR_API_TOKEN" +} +``` + +## Running The Provider + +To plan and apply your Terraform configuration: + +1. Initialize your configuration: + +```bash +terraform init -plugin-dir=~/.terraform.d/plugins +``` + +2. Plan your changes: + +```bash +terraform plan +``` + +3. Apply your configuration: + +```bash +terraform apply +``` + +## Debugging + +If you encounter any issues or unexpected behaviors, enable debug mode by setting the environment variable: + +```bash +export TF_PROVIDER_DEBUG=true +``` + +Then, run your Terraform commands. + +## Running Tests + +1. Generate the docs: + +```bash +go generate ./... +``` + +2. To execute the provider's tests, follow these steps: + +**a. Run Unit Tests**: + +```bash +make unit-test +``` + +**b. Run Acceptance Tests**: + +```bash +make acceptance-test +``` + +## Publishing the Provider + +1. Tag your release: + +```bash +git tag v0.2.7 +git push --tags +``` + +2. Build a release binary for your platform: + +```bash +GOOS=linux GOARCH=amd64 go build -o terraform-provider-abbey +``` + +3. Upload the binary to the GitHub release or any other distribution method you prefer. + +Note: For wide-reaching utility, consider registering your provider with the official Terraform provider registry once +it becomes popular within the community. diff --git a/RELEASES.md b/RELEASES.md deleted file mode 100644 index 3da5c30..0000000 --- a/RELEASES.md +++ /dev/null @@ -1,85 +0,0 @@ - - -## 2023-06-23 20:28:15 -### Changes -Based on: -- OpenAPI Doc 0.1.0 -- Speakeasy CLI 1.50.1 (2.43.2) https://github.com/speakeasy-api/speakeasy - -## 2023-06-23 23:30:03 -### Changes -Based on: -- OpenAPI Doc 0.1.0 -- Speakeasy CLI 1.50.1 (2.43.2) https://github.com/speakeasy-api/speakeasy - -## 2023-07-10 19:36:58 -### Changes -Based on: -- OpenAPI Doc 0.1.0 -- Speakeasy CLI 1.55.0 (2.59.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-10 21:58:11 -### Changes -Based on: -- OpenAPI Doc 0.1.0 -- Speakeasy CLI 1.55.0 (2.59.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-10 23:38:26 -### Changes -Based on: -- OpenAPI Doc 0.1.0 -- Speakeasy CLI 1.56.0 (2.61.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-11 00:21:24 -### Changes -Based on: -- OpenAPI Doc 0.1.0 -- Speakeasy CLI 1.56.0 (2.61.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-22 00:10:30 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.64.0 (2.71.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-25 00:04:23 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.64.1 (2.71.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-25 21:07:40 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.65.0 (2.73.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-26 00:04:10 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.65.0 (2.73.0) https://github.com/speakeasy-api/speakeasy - -## 2023-07-27 00:04:06 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.65.1 (2.73.1) https://github.com/speakeasy-api/speakeasy - -## 2023-07-27 04:31:21 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.65.1 (2.73.1) https://github.com/speakeasy-api/speakeasy - -## 2023-07-28 00:03:45 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.65.2 (2.75.1) https://github.com/speakeasy-api/speakeasy - -## 2023-07-28 21:38:48 -### Changes -Based on: -- OpenAPI Doc v1 -- Speakeasy CLI 1.65.2 (2.75.1) https://github.com/speakeasy-api/speakeasy \ No newline at end of file diff --git a/USAGE.md b/USAGE.md deleted file mode 100755 index d45e8dc..0000000 --- a/USAGE.md +++ /dev/null @@ -1,16 +0,0 @@ - -## Testing the provider locally - -Should you want to validate a change locally, the `--debug` flag allows you to execute the provider against a terraform instance locally. - -This also allows for debuggers (e.g. delve) to be attached to the provider. - -```sh -go run main.go --debug -# Copy the TF_REATTACH_PROVIDERS env var -# In a new terminal -cd examples/your-example -TF_REATTACH_PROVIDERS=... terraform init -TF_REATTACH_PROVIDERS=... terraform apply -``` - \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index b44db0c..27cc3d6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,107 +1,17 @@ --- -page_title: "Provider: Abbey" +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: 'abbey Provider' +subcategory: '' description: |- - The Abbey provider is used by security teams and DevOps/DevSecOps engineers to automate and secure - access to sensitive resources. --- -# Abbey Provider +# abbey Provider -The Abbey provider is used by security teams and DevOps/DevSecOps engineers to automate and secure -access to sensitive resources in their existing cloud infrastructure. + -Resources in this provider interact with endpoints from the Abbey API and needs to be -configured with credentials before it can used. +## Schema -## Background +### Required -Abbey is a platform for security teams and DevOps/DevSecOps engineers to -automate and secure access to sensitive resources. - -With Abbey, you can improve your security and compliance programs by automatically controlling -and right-sizing permissions so the risks around unauthorized access is limited in the event of a breach. - -You do this by leveraging your normal Infrastructure as Code (IaC) tooling — -Terraform, CI/CD systems, secrets managers, and Terraform wrappers. -Abbey provides a Terraform plugin and platform that extends your Infrastructure as Code capabilities -from Infrastructure to Identity, Access, and Management (IAM). - -## Contributing - -Development happens in the [GitHub repo](https://github.com/abbeylabs/terraform-provider-abbey): - -- [Releases](https://github.com/abbeylabs/terraform-provider-abbey/releases) -- [Issues](https://github.com/abbeylabs/terraform-provider-abbey/issues) - -## Example Usage - -```terraform -terraform { - required_providers { - abbey = { - source = "abbeylabs/abbey" - } - } -} - -provider "abbey" { - bearer_auth = "" -} - -resource "abbey_grant_kit" "example" { - name = "example_grant_kit" - description = "Example description." - - workflow = { - steps = [ - { - reviewers = { - one_of = ["replace-me@example.com"] - } - skip_if = [ - { bundle = "github://organization/repository/path/to/bundle" } - ] - } - ] - } - - policies = [ - { bundle = "github://organization/repository/path/to/bundle" } - ] - - output = { - location = "github://organization/repo/path/to/access.tf" - append = <<-EOT - resource "abbey_demo" "my_demo" { - permission = "read_write" - email = "replace-me@example.com" - } - EOT - } -} -``` - -## Authentication - -Abbey provides the following methods for authenticating to the Abbey API: - -- Abbey Token - -### Generating Tokens - -You can generate an Abbey Token by: - -- [Abbey Developers Dashboard](https://app.abbey.io/developers) -> New API Key -> Create - -### Using Tokens - -Configure your Abbey `provider` block with a `bearer_auth` string. - -```hcl -provider "abbey" { - bearer_auth = "" -} -``` - -For better security practice, you should place your token into a variable in your `variables.tf` file and set it -using an environment variable or secret store. +- `bearer_auth` (String, Sensitive) The authentication token. +- `server_url` (String) The API host. diff --git a/docs/resources/demo.md b/docs/resources/demo.md index ee897ea..43c9468 100644 --- a/docs/resources/demo.md +++ b/docs/resources/demo.md @@ -1,37 +1,24 @@ --- # generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "abbey_demo Resource - terraform-provider-abbey" -subcategory: "" +page_title: 'abbey_demo Resource - abbey' +subcategory: '' description: |- - Demo Resource --- # abbey_demo (Resource) -Demo Resource - -## Example Usage - -```terraform -resource "abbey_demo" "my_demo" { - permission = "read_write" - email = "alice@example.com" -} -``` - -## Schema -### Optional - -- `email` (String) -- `permission` (String) must be one of [read_write] +## Schema -### Read-Only +### Required -- `created_at` (String) -- `id` (Number) The ID of this resource. -- `updated_at` (String) -- `user_id` (String) +- `email` (String) The email of the user +- `permission` (String) permission +### Optional +- `created_at` (String) created_at +- `id` (Number) id +- `updated_at` (String) updated_at +- `user_id` (String) user_id diff --git a/docs/resources/grant_kit.md b/docs/resources/grant_kit.md index 95d68a2..8c86909 100644 --- a/docs/resources/grant_kit.md +++ b/docs/resources/grant_kit.md @@ -1,202 +1,166 @@ --- # generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "abbey_grant_kit Resource - terraform-provider-abbey" -subcategory: "" +page_title: 'abbey_grant_kit Resource - abbey' +subcategory: '' description: |- - GrantKit Resource --- # abbey_grant_kit (Resource) -GrantKit Resource - -## Example Usage - -```terraform -resource "abbey_grant_kit" "my_grant_kit" { - name = "my_grant_kit" - description = "My description." - - workflow = { - steps = [ - { - reviewers = { - one_of = ["alice@example.com"] - } - }, - { - reviewers = { - all_of = ["bob@example.com", "carol@example.com"] - } - skip_if = [ - { bundle = "github://my-org/my-repo/policies/on-call-overrides" } - ] - } - ] - } - - policies = [ - { bundle = "github://my-org/my-repo/policies/common" } - ] - - output = { - location = "github://my-org/my-repo/access.tf" - append = <<-EOT - resource "abbey_demo" "my_demo" { - permission = "read_write" - email = "alice@example.com" - } - EOT - } -} -``` - + ## Schema ### Required -- `description` (String) -- `name` (String) -- `output` (Attributes) (see [below for nested schema](#nestedatt--output)) +- `description` (String) description +- `name` (String) name +- `output` (Attributes) output (see [below for nested schema](#nestedatt--output)) ### Optional -- `policies` (Attributes List) (see [below for nested schema](#nestedatt--policies)) -- `workflow` (Attributes) (see [below for nested schema](#nestedatt--workflow)) - -### Read-Only - -- `created_at` (String) -- `current_version_id` (String) -- `grants` (Attributes List) (see [below for nested schema](#nestedatt--grants)) -- `id` (String) The ID of this resource. -- `requests` (Attributes List) (see [below for nested schema](#nestedatt--requests)) -- `updated_at` (String) +- `created_at` (String) created_at +- `current_version_id` (String) current_version_id +- `grants` (Attributes List) grants (see [below for nested schema](#nestedatt--grants)) +- `id` (String) id +- `max_grant_duration_in_sec` (Number) max_grant_duration_in_sec +- `policies` (Attributes List) policies (see [below for nested schema](#nestedatt--policies)) +- `requests` (Attributes List) requests (see [below for nested schema](#nestedatt--requests)) +- `resource_type` (String) resource_type +- `updated_at` (String) updated_at +- `workflow` (Attributes) workflow (see [below for nested schema](#nestedatt--workflow)) + ### Nested Schema for `output` Required: -- `location` (String) +- `location` (String) location Optional: -- `append` (String) -- `overwrite` (String) +- `append` (String) append +- `overwrite` (String) overwrite + + + +### Nested Schema for `grants` + +Required: +- `created_at` (String) created_at +- `deleted` (Boolean) deleted +- `grant_kit_id` (String) grant_kit_id +- `grant_kit_version_id` (String) grant_kit_version_id +- `id` (String) id +- `organization_id` (String) organization_id +- `request_id` (String) request_id +- `updated_at` (String) updated_at +- `user_id` (String) user_id + ### Nested Schema for `policies` Optional: -- `bundle` (String) -- `query` (String) +- `bundle` (String) bundle +- `query` (String) query + - -### Nested Schema for `workflow` +### Nested Schema for `requests` + +Required: + +- `created_at` (String) created_at +- `grant_id` (String) grant_id +- `grant_kit_id` (String) grant_kit_id +- `grant_kit_version_id` (String) grant_kit_version_id +- `id` (String) id +- `pull_request` (String) pull_request +- `reason` (String) reason +- `status` (String) status +- `updated_at` (String) updated_at +- `user_id` (String) user_id Optional: -- `steps` (Attributes List) (see [below for nested schema](#nestedatt--workflow--steps)) +- `grant_kit_name` (String) grant_kit_name +- `reviews` (Attributes List) reviews (see [below for nested schema](#nestedatt--requests--reviews)) - -### Nested Schema for `workflow.steps` + -Optional: +### Nested Schema for `requests.reviews` -- `reviewers` (Attributes) (see [below for nested schema](#nestedatt--workflow--steps--reviewers)) -- `skip_if` (Attributes List) (see [below for nested schema](#nestedatt--workflow--steps--skip_if)) +Required: - -### Nested Schema for `workflow.steps.reviewers` +- `created_at` (String) created_at +- `grant_id` (String) grant_id +- `grant_kit_name` (String) grant_kit_name +- `grant_kit_version_id` (String) grant_kit_version_id +- `id` (String) id +- `pull_request` (String) pull_request +- `reason` (String) reason +- `request_id` (String) request_id +- `request_reason` (String) request_reason +- `status` (String) status +- `updated_at` (String) updated_at +- `user_id` (String) user_id Optional: -- `all_of` (List of String) -- `one_of` (List of String) +- `grant` (Attributes) grant (see [below for nested schema](#nestedatt--requests--reviews--grant)) +- `user_email` (String) user_email + - -### Nested Schema for `workflow.steps.skip_if` +### Nested Schema for `requests.reviews.grant` -Optional: +Required: -- `bundle` (String) -- `query` (String) +- `created_at` (String) created_at +- `deleted` (Boolean) deleted +- `grant_kit_id` (String) grant_kit_id +- `grant_kit_version_id` (String) grant_kit_version_id +- `id` (String) id +- `organization_id` (String) organization_id +- `request_id` (String) request_id +- `updated_at` (String) updated_at +- `user_id` (String) user_id + +### Nested Schema for `workflow` +Optional: - -### Nested Schema for `grants` +- `steps` (Attributes List) steps (see [below for nested schema](#nestedatt--workflow--steps)) -Read-Only: + -- `created_at` (String) -- `deleted` (Boolean) -- `grant_kit_id` (String) -- `grant_kit_version_id` (String) -- `id` (String) -- `organization_id` (String) -- `request_id` (String) -- `updated_at` (String) -- `user_id` (String) +### Nested Schema for `workflow.steps` +Optional: - -### Nested Schema for `requests` +- `reviewers` (Attributes) reviewers (see [below for nested schema](#nestedatt--workflow--steps--reviewers)) +- `skip_if` (Attributes List) skip_if (see [below for nested schema](#nestedatt--workflow--steps--skip_if)) -Read-Only: - -- `created_at` (String) -- `grant_id` (String) -- `grant_kit_id` (String) -- `grant_kit_name` (String) -- `grant_kit_version_id` (String) -- `id` (String) -- `pull_request` (String) -- `reason` (String) -- `reviews` (Attributes List) (see [below for nested schema](#nestedatt--requests--reviews)) -- `status` (String) must be one of [Pending, Denied, Approved, Canceled] -- `updated_at` (String) -- `user_id` (String) + - -### Nested Schema for `requests.reviews` +### Nested Schema for `workflow.steps.reviewers` -Read-Only: - -- `created_at` (String) -- `grant` (Attributes) Success (see [below for nested schema](#nestedatt--requests--reviews--grant)) -- `grant_id` (String) -- `grant_kit_name` (String) -- `grant_kit_version_id` (String) -- `id` (String) -- `pull_request` (String) -- `reason` (String) -- `request_id` (String) -- `status` (String) must be one of [Pending, Denied, Approved, Canceled] -- `updated_at` (String) -- `user_email` (String) -- `user_id` (String) +Optional: - -### Nested Schema for `requests.reviews.grant` +- `all_of` (List of String) all_of +- `one_of` (List of String) one_of -Read-Only: + -- `created_at` (String) -- `deleted` (Boolean) -- `grant_kit_id` (String) -- `grant_kit_version_id` (String) -- `id` (String) -- `organization_id` (String) -- `request_id` (String) -- `updated_at` (String) -- `user_id` (String) +### Nested Schema for `workflow.steps.skip_if` +Optional: +- `bundle` (String) bundle +- `query` (String) query diff --git a/docs/resources/identity.md b/docs/resources/identity.md index a9cf16f..102e055 100644 --- a/docs/resources/identity.md +++ b/docs/resources/identity.md @@ -1,42 +1,24 @@ --- # generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "abbey_identity Resource - terraform-provider-abbey" -subcategory: "" +page_title: 'abbey_identity Resource - abbey' +subcategory: '' description: |- - Identity Resource --- # abbey_identity (Resource) -Identity Resource - -## Example Usage - -```terraform -resource "abbey_identity" "my_identity" { - abbey_account = "alice@example.com" - source = "mysource" - metadata = jsonencode( - { - "mykey" = "myvalue" - } - ) -} -``` - + ## Schema ### Required -- `abbey_account` (String) +- `abbey_account` (String) abbey_account - `metadata` (String) Json encoded string. See documentation for details. -- `source` (String) - -### Read-Only - -- `created_at` (String) -- `id` (String) The ID of this resource. -- `updated_at` (String) +- `source` (String) source +### Optional +- `created_at` (String) created_at +- `id` (String) id +- `updated_at` (String) updated_at diff --git a/examples/README.md b/examples/README.md deleted file mode 100755 index f87f5c1..0000000 --- a/examples/README.md +++ /dev/null @@ -1 +0,0 @@ -# TODO \ No newline at end of file diff --git a/examples/provider-install-verification/main.tf b/examples/provider-install-verification/main.tf deleted file mode 100644 index 6c2cd0d..0000000 --- a/examples/provider-install-verification/main.tf +++ /dev/null @@ -1,43 +0,0 @@ -terraform { - required_providers { - abbey = { - source = "abbeylabs/abbey" - } - } -} - -provider "abbey" { - bearer_auth = "" -} - -resource "abbey_grant_kit" "example" { - name = "example_grant_kit" - description = "Example description." - - workflow = { - steps = [ - { - reviewers = { - one_of = ["replace-me@example.com"] - } - skip_if = [ - { bundle = "github://organization/repository/path/to/bundle" } - ] - } - ] - } - - policies = [ - { bundle = "github://organization/repository/path/to/bundle" } - ] - - output = { - location = "github://organization/repo/path/to/access.tf" - append = <<-EOT - resource "abbey_demo" "my_demo" { - permission = "read_write" - email = "replace-me@example.com" - } - EOT - } -} diff --git a/examples/provider/main.tf b/examples/provider/main.tf new file mode 100644 index 0000000..fdd861d --- /dev/null +++ b/examples/provider/main.tf @@ -0,0 +1,16 @@ +terraform { + required_providers { + abbey = { + source = "hashicorp.com/edu/abbey" + version = "0.2.7" + } + } +} + +provider "abbey" { + + server_url = "https://api.abbey.io/v1" + + bearer_auth = "MY_TOKEN" + +} diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf deleted file mode 100755 index 5fe44af..0000000 --- a/examples/provider/provider.tf +++ /dev/null @@ -1,13 +0,0 @@ -terraform { - required_providers { - abbey = { - source = "abbeylabs/abbey" - version = "0.2.4" - } - } -} - -provider "abbey" { - # Configuration options - bearer_auth = "" -} \ No newline at end of file diff --git a/examples/resources/abbey_demo/resource.tf b/examples/resources/abbey_demo/resource.tf deleted file mode 100755 index 73f913a..0000000 --- a/examples/resources/abbey_demo/resource.tf +++ /dev/null @@ -1,4 +0,0 @@ -resource "abbey_demo" "my_demo" { - permission = "read_write" - email = "alice@example.com" -} \ No newline at end of file diff --git a/examples/resources/abbey_grant_kit/resource.tf b/examples/resources/abbey_grant_kit/resource.tf deleted file mode 100755 index 7cf40c5..0000000 --- a/examples/resources/abbey_grant_kit/resource.tf +++ /dev/null @@ -1,36 +0,0 @@ -resource "abbey_grant_kit" "my_grant_kit" { - name = "my_grant_kit" - description = "My description." - - workflow = { - steps = [ - { - reviewers = { - one_of = ["alice@example.com"] - } - }, - { - reviewers = { - all_of = ["bob@example.com", "carol@example.com"] - } - skip_if = [ - { bundle = "github://my-org/my-repo/policies/on-call-overrides" } - ] - } - ] - } - - policies = [ - { bundle = "github://my-org/my-repo/policies/common" } - ] - - output = { - location = "github://my-org/my-repo/access.tf" - append = <<-EOT - resource "abbey_demo" "my_demo" { - permission = "read_write" - email = "alice@example.com" - } - EOT - } -} \ No newline at end of file diff --git a/examples/resources/abbey_identity/resource.tf b/examples/resources/abbey_identity/resource.tf deleted file mode 100755 index 151f393..0000000 --- a/examples/resources/abbey_identity/resource.tf +++ /dev/null @@ -1,9 +0,0 @@ -resource "abbey_identity" "my_identity" { - abbey_account = "alice@example.com" - source = "mysource" - metadata = jsonencode( - { - "mykey" = "myvalue" - } - ) -} \ No newline at end of file diff --git a/examples/resources/demo/main.tf b/examples/resources/demo/main.tf new file mode 100644 index 0000000..f6975a2 --- /dev/null +++ b/examples/resources/demo/main.tf @@ -0,0 +1,6 @@ +resource "abbey_demo" "example" { + email = "email" + + permission = "permission" + +} diff --git a/examples/resources/grantkit/main.tf b/examples/resources/grantkit/main.tf new file mode 100644 index 0000000..f716538 --- /dev/null +++ b/examples/resources/grantkit/main.tf @@ -0,0 +1,46 @@ +resource "abbey_grant_kit" "example" { + name = "name" + + description = "description" + + workflow = { + steps = [ + { + reviewers = { + one_of = [ + "one_of" + ] + all_of = [ + "all_of" + ] + } + + skip_if = [ + { + bundle = "bundle" + query = "query" + } + + ] + } + + ] + } + + + policies = [ + { + bundle = "bundle" + query = "query" + } + + ] + + output = { + location = "location" + append = "append" + overwrite = "overwrite" + } + + +} diff --git a/examples/resources/identity/main.tf b/examples/resources/identity/main.tf new file mode 100644 index 0000000..6edc05d --- /dev/null +++ b/examples/resources/identity/main.tf @@ -0,0 +1,8 @@ +resource "abbey_identity" "example" { + abbey_account = "abbey_account" + + source = "source" + + metadata = "metadata" + +} diff --git a/files.gen b/files.gen deleted file mode 100755 index a11a94d..0000000 --- a/files.gen +++ /dev/null @@ -1,156 +0,0 @@ -internal/sdk/apikeys.go -internal/sdk/connectionspecs.go -internal/sdk/connections.go -internal/sdk/demo.go -internal/sdk/grantkits.go -internal/sdk/grants.go -internal/sdk/identities.go -internal/sdk/requests.go -internal/sdk/reviews.go -internal/sdk/sdk.go -internal/provider/type_grant.go -internal/provider/type_output.go -internal/provider/type_policy.go -internal/provider/type_review.go -internal/provider/type_request.go -internal/provider/type_reviewers.go -internal/provider/type_step.go -internal/provider/type_grant_workflow.go -go.mod -go.sum -internal/planmodifiers/boolplanmodifier/suppress_diff.go -internal/planmodifiers/float64planmodifier/suppress_diff.go -internal/planmodifiers/int64planmodifier/suppress_diff.go -internal/planmodifiers/listplanmodifier/suppress_diff.go -internal/planmodifiers/mapplanmodifier/suppress_diff.go -internal/planmodifiers/numberplanmodifier/suppress_diff.go -internal/planmodifiers/objectplanmodifier/suppress_diff.go -internal/planmodifiers/setplanmodifier/suppress_diff.go -internal/planmodifiers/stringplanmodifier/suppress_diff.go -internal/planmodifiers/utils/state_check.go -internal/provider/reflect/diags.go -internal/provider/reflect/doc.go -internal/provider/reflect/generic_attr_value.go -internal/provider/reflect/helpers.go -internal/provider/reflect/interfaces.go -internal/provider/reflect/into.go -internal/provider/reflect/map.go -internal/provider/reflect/number.go -internal/provider/reflect/options.go -internal/provider/reflect/outof.go -internal/provider/reflect/pointer.go -internal/provider/reflect/primitive.go -internal/provider/reflect/slice.go -internal/provider/reflect/struct.go -internal/provider/utils.go -internal/sdk/pkg/types/bigint.go -internal/sdk/pkg/types/date.go -internal/sdk/pkg/types/datetime.go -internal/sdk/pkg/utils/contenttype.go -internal/sdk/pkg/utils/form.go -internal/sdk/pkg/utils/headers.go -internal/sdk/pkg/utils/pathparams.go -internal/sdk/pkg/utils/queryparams.go -internal/sdk/pkg/utils/requestbody.go -internal/sdk/pkg/utils/retries.go -internal/sdk/pkg/utils/security.go -internal/sdk/pkg/utils/utils.go -internal/validators/DateValidator.go -internal/validators/ExactlyOneChild.go -internal/validators/JSONParseValidator.go -internal/validators/RFC3339Validator.go -main.go -terraform-registry-manifest.json -tools/tools.go -internal/sdk/pkg/models/operations/createapikey.go -internal/sdk/pkg/models/operations/getapikeys.go -internal/sdk/pkg/models/operations/deleteapikey.go -internal/sdk/pkg/models/operations/listconnectionspecs.go -internal/sdk/pkg/models/operations/createconnection.go -internal/sdk/pkg/models/operations/getconnection.go -internal/sdk/pkg/models/operations/listconnections.go -internal/sdk/pkg/models/operations/updateconnection.go -internal/sdk/pkg/models/operations/createdemo.go -internal/sdk/pkg/models/operations/deletedemo.go -internal/sdk/pkg/models/operations/getdemo.go -internal/sdk/pkg/models/operations/creategrantkit.go -internal/sdk/pkg/models/operations/listgrantkits.go -internal/sdk/pkg/models/operations/deletegrantkit.go -internal/sdk/pkg/models/operations/getgrantkitbyid.go -internal/sdk/pkg/models/operations/listgrantkitversionsbyid.go -internal/sdk/pkg/models/operations/updategrantkit.go -internal/sdk/pkg/models/operations/listgrants.go -internal/sdk/pkg/models/operations/getgrantbyid.go -internal/sdk/pkg/models/operations/revokegrant.go -internal/sdk/pkg/models/operations/createidentity.go -internal/sdk/pkg/models/operations/deleteidentity.go -internal/sdk/pkg/models/operations/getidentity.go -internal/sdk/pkg/models/operations/updateidentity.go -internal/sdk/pkg/models/operations/cancelrequestbyid.go -internal/sdk/pkg/models/operations/createrequest.go -internal/sdk/pkg/models/operations/getrequestbyid.go -internal/sdk/pkg/models/operations/listrequests.go -internal/sdk/pkg/models/operations/listreviews.go -internal/sdk/pkg/models/operations/approvereview.go -internal/sdk/pkg/models/operations/denyreview.go -internal/sdk/pkg/models/operations/getreviewbyid.go -internal/sdk/pkg/models/shared/error.go -internal/sdk/pkg/models/shared/apikey.go -internal/sdk/pkg/models/shared/apikeyscreateparams.go -internal/sdk/pkg/models/shared/apikeys.go -internal/sdk/pkg/models/shared/connectionspeclisting.go -internal/sdk/pkg/models/shared/connectionspec.go -internal/sdk/pkg/models/shared/connectionrequestspec.go -internal/sdk/pkg/models/shared/connectionauth.go -internal/sdk/pkg/models/shared/oauth2flow.go -internal/sdk/pkg/models/shared/keyvaluepair.go -internal/sdk/pkg/models/shared/oauth2flowpkce.go -internal/sdk/pkg/models/shared/pkcemethod.go -internal/sdk/pkg/models/shared/oauth2flowexchange.go -internal/sdk/pkg/models/shared/requestspec.go -internal/sdk/pkg/models/shared/httpmethod.go -internal/sdk/pkg/models/shared/requestcontenttype.go -internal/sdk/pkg/models/shared/connectionauthtypeenum.go -internal/sdk/pkg/models/shared/connection.go -internal/sdk/pkg/models/shared/connectiontype.go -internal/sdk/pkg/models/shared/connectionparams.go -internal/sdk/pkg/models/shared/connectionparamsgithubvariant.go -internal/sdk/pkg/models/shared/connectionparamsgithub.go -internal/sdk/pkg/models/shared/pagerdutyconnectionvalue.go -internal/sdk/pkg/models/shared/pagerdutyconnection.go -internal/sdk/pkg/models/shared/connectionlisting.go -internal/sdk/pkg/models/shared/connectionupdateparams.go -internal/sdk/pkg/models/shared/demo.go -internal/sdk/pkg/models/shared/demoparams.go -internal/sdk/pkg/models/shared/grantkit.go -internal/sdk/pkg/models/shared/grantworkflow.go -internal/sdk/pkg/models/shared/step.go -internal/sdk/pkg/models/shared/policy.go -internal/sdk/pkg/models/shared/reviewers.go -internal/sdk/pkg/models/shared/request.go -internal/sdk/pkg/models/shared/requeststatus.go -internal/sdk/pkg/models/shared/review.go -internal/sdk/pkg/models/shared/reviewstatus.go -internal/sdk/pkg/models/shared/grant.go -internal/sdk/pkg/models/shared/output.go -internal/sdk/pkg/models/shared/grantkitcreateparams.go -internal/sdk/pkg/models/shared/grantkitversion.go -internal/sdk/pkg/models/shared/grantkitupdateparams.go -internal/sdk/pkg/models/shared/identity.go -internal/sdk/pkg/models/shared/identityparams.go -internal/sdk/pkg/models/shared/requestcancelparams.go -internal/sdk/pkg/models/shared/requestparams.go -internal/sdk/pkg/models/shared/reviewupdateparams.go -internal/sdk/pkg/models/shared/security.go -USAGE.md -internal/provider/provider.go -internal/provider/demo_resource.go -internal/provider/demo_resource_sdk.go -internal/provider/grantkit_resource.go -internal/provider/grantkit_resource_sdk.go -internal/provider/identity_resource.go -internal/provider/identity_resource_sdk.go -internal/provider/grantkit_data_source.go -internal/provider/grantkit_data_source_sdk.go -internal/provider/identity_data_source.go -internal/provider/identity_data_source_sdk.go diff --git a/gen.yaml b/gen.yaml deleted file mode 100755 index 56b6cfa..0000000 --- a/gen.yaml +++ /dev/null @@ -1,13 +0,0 @@ -configVersion: 1.0.0 -management: - docChecksum: 73c07ff157bbd13199a5e11925950ef4 - docVersion: v1 - speakeasyVersion: 1.65.2 - generationVersion: 2.75.1 -generation: - sdkClassName: SDK - singleTagPerOp: false -terraform: - version: 2.2.1 - author: abbeylabs - packageName: abbey diff --git a/go.mod b/go.mod old mode 100755 new mode 100644 index 157417d..ce96768 --- a/go.mod +++ b/go.mod @@ -1,63 +1,81 @@ module abbey/v2 -go 1.18 +go 1.19 require ( - github.com/cenkalti/backoff/v4 v4.2.0 - github.com/hashicorp/terraform-plugin-framework v1.3.0 - github.com/hashicorp/terraform-plugin-go v0.15.0 + github.com/go-provider-sdk v0.0.0 + github.com/hashicorp/terraform-plugin-docs v0.16.0 + github.com/hashicorp/terraform-plugin-framework v1.3.5 + github.com/hashicorp/terraform-plugin-go v0.18.0 + github.com/hashicorp/terraform-plugin-testing v1.5.1 + github.com/stretchr/testify v1.8.4 ) require ( - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.1.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.2 // indirect - github.com/armon/go-radix v1.0.0 // indirect - github.com/bgentry/speakeasy v0.1.0 // indirect - github.com/fatih/color v1.13.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-checkpoint v0.5.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.4.9 // indirect - github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hc-install v0.4.0 // indirect - github.com/hashicorp/terraform-exec v0.17.2 // indirect - github.com/hashicorp/terraform-json v0.14.0 // indirect - github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect - github.com/hashicorp/terraform-registry-address v0.2.0 // indirect - github.com/hashicorp/terraform-svchost v0.0.1 // indirect - github.com/huandu/xstrings v1.3.2 // indirect - github.com/imdario/mergo v0.3.13 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect - github.com/mitchellh/cli v1.1.4 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/oklog/run v1.0.0 // indirect - github.com/posener/complete v1.2.3 // indirect - github.com/russross/blackfriday v1.6.0 // indirect - github.com/shopspring/decimal v1.3.1 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zclconf/go-cty v1.12.1 // indirect - golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect - google.golang.org/grpc v1.54.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.1.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.2 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect + github.com/agext/levenshtein v1.2.2 // indirect + github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/cloudflare/circl v1.3.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-checkpoint v0.5.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.4.10 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/hc-install v0.5.2 // indirect + github.com/hashicorp/hcl/v2 v2.17.0 // indirect + github.com/hashicorp/logutils v1.0.0 // indirect + github.com/hashicorp/terraform-exec v0.18.1 // indirect + github.com/hashicorp/terraform-json v0.17.1 // indirect + github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.28.0 // indirect + github.com/hashicorp/terraform-registry-address v0.2.1 // indirect + github.com/hashicorp/terraform-svchost v0.1.1 // indirect + github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect + github.com/huandu/xstrings v1.3.2 // indirect + github.com/imdario/mergo v0.3.13 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mitchellh/cli v1.1.5 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/posener/complete v1.2.3 // indirect + github.com/russross/blackfriday v1.6.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/zclconf/go-cty v1.13.3 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 // indirect + golang.org/x/mod v0.11.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.56.1 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) -require ( - github.com/hashicorp/terraform-plugin-docs v0.13.0 - github.com/hashicorp/terraform-plugin-framework-validators v0.10.0 - github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect -) +replace github.com/go-provider-sdk => ./internal/client diff --git a/go.sum b/go.sum old mode 100755 new mode 100644 index d555d87..cb5cde8 --- a/go.sum +++ b/go.sum @@ -1,60 +1,49 @@ -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI= +github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= -github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= -github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= +github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= -github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= -github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= -github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= +github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -67,89 +56,90 @@ github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuD github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= +github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= -github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk= +github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= -github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= -github.com/hashicorp/terraform-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad8zszYZ73Go= -github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8= -github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= -github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= -github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smPzZrt1Wlm9koLeKazY= -github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ= -github.com/hashicorp/terraform-plugin-framework v1.3.0 h1:WtP1CIaWAfbzME17xoUXvJcyh5Ewu9attdhbfWNnYLs= -github.com/hashicorp/terraform-plugin-framework v1.3.0/go.mod h1:A1WD3Ry7FhrThViUTbkx4ZDsMq9oaAv4U9oTI8bBzCU= -github.com/hashicorp/terraform-plugin-framework-validators v0.10.0 h1:4L0tmy/8esP6OcvocVymw52lY0HyQ5OxB7VNl7k4bS0= -github.com/hashicorp/terraform-plugin-framework-validators v0.10.0/go.mod h1:qdQJCdimB9JeX2YwOpItEu+IrfoJjWQ5PhLpAOMDQAE= -github.com/hashicorp/terraform-plugin-go v0.15.0 h1:1BJNSUFs09DS8h/XNyJNJaeusQuWc/T9V99ylU9Zwp0= -github.com/hashicorp/terraform-plugin-go v0.15.0/go.mod h1:tk9E3/Zx4RlF/9FdGAhwxHExqIHHldqiQGt20G6g+nQ= +github.com/hashicorp/hc-install v0.5.2 h1:SfwMFnEXVVirpwkDuSF5kymUOhrUxrTq3udEseZdOD0= +github.com/hashicorp/hc-install v0.5.2/go.mod h1:9QISwe6newMWIfEiXpzuu1k9HAGtQYgnSH8H9T8wmoI= +github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= +github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4= +github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980= +github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= +github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= +github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= +github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= +github.com/hashicorp/terraform-plugin-framework v1.3.5 h1:FJ6s3CVWVAxlhiF/jhy6hzs4AnPHiflsp9KgzTGl1wo= +github.com/hashicorp/terraform-plugin-framework v1.3.5/go.mod h1:2gGDpWiTI0irr9NSTLFAKlTi6KwGti3AoU19rFqU30o= +github.com/hashicorp/terraform-plugin-go v0.18.0 h1:IwTkOS9cOW1ehLd/rG0y+u/TGLK9y6fGoBjXVUquzpE= +github.com/hashicorp/terraform-plugin-go v0.18.0/go.mod h1:l7VK+2u5Kf2y+A+742GX0ouLut3gttudmvMgN0PA74Y= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-registry-address v0.2.0 h1:92LUg03NhfgZv44zpNTLBGIbiyTokQCDcdH5BhVHT3s= -github.com/hashicorp/terraform-registry-address v0.2.0/go.mod h1:478wuzJPzdmqT6OGbB/iH82EDcI8VFM4yujknh/1nIs= -github.com/hashicorp/terraform-svchost v0.0.1 h1:Zj6fR5wnpOHnJUmLyWozjMeDaVuE+cstMPj41/eKmSQ= -github.com/hashicorp/terraform-svchost v0.0.1/go.mod h1:ut8JaH0vumgdCfJaihdcZULqkAwHdQNwNH7taIDdsZM= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.28.0 h1:gY4SG34ANc6ZSeWEKC9hDTChY0ZiN+Myon17fSA0Xgc= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.28.0/go.mod h1:deXEw/iJXtJxNV9d1c/OVJrvL7Zh0a++v7rzokW6wVY= +github.com/hashicorp/terraform-plugin-testing v1.5.1 h1:T4aQh9JAhmWo4+t1A7x+rnxAJHCDIYW9kXyo4sVO92c= +github.com/hashicorp/terraform-plugin-testing v1.5.1/go.mod h1:dg8clO6K59rZ8w9EshBmDp1CxTIPu3yA4iaDpX1h5u0= +github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM= +github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y= +github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= +github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mitchellh/cli v1.1.4 h1:qj8czE26AU4PbiaPXK5uVmMSM+V5BYsFBiM9HhGRLUA= -github.com/mitchellh/cli v1.1.4/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= +github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -158,104 +148,85 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= -github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= +github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= -github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/zclconf/go-cty v1.13.3 h1:m+b9q3YDbg6Bec5rr+KGy1MzEVzY/jC2X+YX4yqKtHI= +github.com/zclconf/go-cty v1.13.3/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U= +golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/client/.gitignore b/internal/client/.gitignore new file mode 100644 index 0000000..390719b --- /dev/null +++ b/internal/client/.gitignore @@ -0,0 +1,10 @@ +# Binaries and executables +*.exe +*.exe~ +*.dll +*.so +*.dylib +.DStore + +# Output of go coverage +*.out diff --git a/internal/client/README.md b/internal/client/README.md new file mode 100644 index 0000000..749a0a1 --- /dev/null +++ b/internal/client/README.md @@ -0,0 +1,65 @@ +# Client Go SDK 1.0.0 + +A Go SDK for Client. + +- API version: v1 +- SDK version: 1.0.0 + +The public Abbey API. Used for integrating with Abbey and building interfaces to extend the Abbey platform. See https://docs.abbey.io for more information. + +## Table of Contents + +- [Authentication](#authentication) +- [Services](#services) + +## Authentication + +### Access Token + +The client API uses a access token as a form of authentication. + +The access token can be set when initializing the SDK like this: + +```go + +``` + +Or at a later stage: + +```go + +``` + +## Services + +### GrantKitsService + +#### ListGrantKits + +#### CreateGrantKit + +#### GetGrantKitById + +#### UpdateGrantKit + +#### DeleteGrantKit + +### IdentitiesService + +#### ListEnrichedIdentities + +#### CreateIdentity + +#### GetIdentity + +#### UpdateIdentity + +#### DeleteIdentity + +### DemoService + +#### GetDemo + +#### CreateDemo + +#### DeleteDemo diff --git a/internal/client/cmd/examples/example.go b/internal/client/cmd/examples/example.go new file mode 100644 index 0000000..9109823 --- /dev/null +++ b/internal/client/cmd/examples/example.go @@ -0,0 +1,21 @@ +package main + +import ( + "context" + "fmt" + + "github.com/go-provider-sdk/pkg/client" + "github.com/go-provider-sdk/pkg/clientconfig" +) + +func main() { + config := clientconfig.NewConfig() + + client := client.NewClient(config) + + res, err := client.GrantKits.ListGrantKits(context.Background()) + if err != nil { + panic(err) + } + fmt.Printf("%+v", res) +} diff --git a/internal/client/go.mod b/internal/client/go.mod new file mode 100644 index 0000000..49e400a --- /dev/null +++ b/internal/client/go.mod @@ -0,0 +1,3 @@ +module github.com/go-provider-sdk + +go 1.18 diff --git a/internal/client/internal/clients/rest/client.go b/internal/client/internal/clients/rest/client.go new file mode 100644 index 0000000..477ed28 --- /dev/null +++ b/internal/client/internal/clients/rest/client.go @@ -0,0 +1,37 @@ +package rest + +import ( + "github.com/go-provider-sdk/internal/clients/rest/handlers" + "github.com/go-provider-sdk/internal/clients/rest/hooks" + "github.com/go-provider-sdk/internal/clients/rest/httptransport" + "github.com/go-provider-sdk/pkg/clientconfig" +) + +type RestClient[T any] struct { + handlers *handlers.HandlerChain[T] +} + +func NewRestClient[T any](config clientconfig.Config) *RestClient[T] { + defaultHeadersHandler := handlers.NewDefaultHeadersHandler[T]() + retryHandler := handlers.NewRetryHandler[T]() + bearerTokenHandler := handlers.NewAccessTokenHandler[T]() + unmarshalHandler := handlers.NewUnmarshalHandler[T]() + hookHandler := handlers.NewHookHandler[T](hooks.NewDefaultHook()) + terminatingHandler := handlers.NewTerminatingHandler[T]() + + handlers := handlers.BuildHandlerChain[T](). + AddHandler(defaultHeadersHandler). + AddHandler(retryHandler). + AddHandler(bearerTokenHandler). + AddHandler(unmarshalHandler). + AddHandler(hookHandler). + AddHandler(terminatingHandler) + + return &RestClient[T]{ + handlers: handlers, + } +} + +func (client *RestClient[T]) Call(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + return client.handlers.CallApi(request) +} diff --git a/internal/client/internal/clients/rest/handlers/bearer_token_handler.go b/internal/client/internal/clients/rest/handlers/bearer_token_handler.go new file mode 100644 index 0000000..b037151 --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/bearer_token_handler.go @@ -0,0 +1,38 @@ +package handlers + +import ( + "errors" + "fmt" + + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +type AccessTokenHandler[T any] struct { + nextHandler Handler[T] +} + +func NewAccessTokenHandler[T any]() *AccessTokenHandler[T] { + return &AccessTokenHandler[T]{ + nextHandler: nil, + } +} + +func (h *AccessTokenHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + if h.nextHandler == nil { + err := errors.New("Handler chain terminated without terminating handler") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + nextRequest := request.Clone() + if request.Config.AccessToken == nil { + return h.nextHandler.Handle(nextRequest) + } + + nextRequest.SetHeader("Authorization", fmt.Sprintf("Bearer %s", *request.Config.AccessToken)) + + return h.nextHandler.Handle(nextRequest) +} + +func (h *AccessTokenHandler[T]) SetNext(handler Handler[T]) { + h.nextHandler = handler +} diff --git a/internal/client/internal/clients/rest/handlers/default_headers_handler.go b/internal/client/internal/clients/rest/handlers/default_headers_handler.go new file mode 100644 index 0000000..a8feb57 --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/default_headers_handler.go @@ -0,0 +1,43 @@ +package handlers + +import ( + "errors" + + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +type DefaultHeadersHandler[T any] struct { + defaultHeaders map[string]string + nextHandler Handler[T] +} + +func NewDefaultHeadersHandler[T any]() *DefaultHeadersHandler[T] { + defaultHeaders := map[string]string{ + "User-Agent": "liblab/2.0.18 go/1.18", + "Content-type": "application/json", + } + + return &DefaultHeadersHandler[T]{ + defaultHeaders: defaultHeaders, + nextHandler: nil, + } +} + +func (h *DefaultHeadersHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + if h.nextHandler == nil { + err := errors.New("Handler chain terminated without terminating handler") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + nextRequest := request.Clone() + + for key, value := range h.defaultHeaders { + nextRequest.SetHeader(key, value) + } + + return h.nextHandler.Handle(nextRequest) +} + +func (h *DefaultHeadersHandler[T]) SetNext(handler Handler[T]) { + h.nextHandler = handler +} diff --git a/internal/client/internal/clients/rest/handlers/handler_chain.go b/internal/client/internal/clients/rest/handlers/handler_chain.go new file mode 100644 index 0000000..29b73a6 --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/handler_chain.go @@ -0,0 +1,36 @@ +package handlers + +import ( + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +type Handler[T any] interface { + Handle(req httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) + SetNext(handler Handler[T]) +} + +type HandlerChain[T any] struct { + head Handler[T] + tail Handler[T] +} + +func BuildHandlerChain[T any]() *HandlerChain[T] { + return &HandlerChain[T]{} +} + +func (chain *HandlerChain[T]) AddHandler(handler Handler[T]) *HandlerChain[T] { + if chain.head == nil { + chain.head = handler + chain.tail = handler + return chain + } + + chain.tail.SetNext(handler) + chain.tail = handler + + return chain +} + +func (chain *HandlerChain[T]) CallApi(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + return chain.head.Handle(request) +} diff --git a/internal/client/internal/clients/rest/handlers/hook_handler.go b/internal/client/internal/clients/rest/handlers/hook_handler.go new file mode 100644 index 0000000..cf56bc4 --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/hook_handler.go @@ -0,0 +1,65 @@ +package handlers + +import ( + "errors" + + "github.com/go-provider-sdk/internal/clients/rest/hooks" + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +type HookHandler[T any] struct { + nextHandler Handler[T] + hook hooks.Hook +} + +func NewHookHandler[T any](hook hooks.Hook) *HookHandler[T] { + return &HookHandler[T]{ + hook: hook, + nextHandler: nil, + } +} + +func (h *HookHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + if h.nextHandler == nil { + err := errors.New("Handler chain terminated without terminating handler") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + clonedReq := request.Clone() + hookReq := h.hook.BeforeRequest(&clonedReq) + + nextRequest, ok := hookReq.(*httptransport.Request) + if !ok { + err := errors.New("hook returned invalid request") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + response, err := h.nextHandler.Handle(*nextRequest) + if err != nil && err.IsHttpError { + clonedError := err.Clone() + hookError := h.hook.OnError(hookReq, &clonedError) + nextError, ok := hookError.(*httptransport.ErrorResponse[T]) + if !ok { + err := errors.New("hook returned invalid error") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + return nil, nextError + } else if err != nil { + return nil, err + } + + clonedResp := response.Clone() + hookResp := h.hook.AfterResponse(hookReq, &clonedResp) + nextResponse, ok := hookResp.(*httptransport.Response[T]) + if !ok { + err := errors.New("hook returned invalid response") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + return nextResponse, nil +} + +func (h *HookHandler[T]) SetNext(handler Handler[T]) { + h.nextHandler = handler +} diff --git a/internal/client/internal/clients/rest/handlers/request_validation_handler.go b/internal/client/internal/clients/rest/handlers/request_validation_handler.go new file mode 100644 index 0000000..ccd9d24 --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/request_validation_handler.go @@ -0,0 +1,41 @@ +package handlers + +import ( + "errors" + + "github.com/go-provider-sdk/internal/clients/rest/httptransport" + "github.com/go-provider-sdk/internal/validation" +) + +type RequestValidationHandler[T any] struct { + nextHandler Handler[T] +} + +func NewRequestValidationHandler[T any]() *RequestValidationHandler[T] { + return &RequestValidationHandler[T]{ + nextHandler: nil, + } +} + +func (h *RequestValidationHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + if h.nextHandler == nil { + err := errors.New("Handler chain terminated without terminating handler") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + err := validation.ValidateData(request.Body) + if err != nil { + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + err = validation.ValidateData(request.Options) + if err != nil { + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + return h.nextHandler.Handle(request) +} + +func (h *RequestValidationHandler[T]) SetNext(handler Handler[T]) { + h.nextHandler = handler +} diff --git a/internal/client/internal/clients/rest/handlers/response_validation_handler.go b/internal/client/internal/clients/rest/handlers/response_validation_handler.go new file mode 100644 index 0000000..16b5250 --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/response_validation_handler.go @@ -0,0 +1,41 @@ +package handlers + +import ( + "errors" + + "github.com/go-provider-sdk/internal/clients/rest/httptransport" + "github.com/go-provider-sdk/internal/validation" +) + +type ResponseValidationHandler[T any] struct { + nextHandler Handler[T] +} + +func NewResponseValidationHandler[T any]() *ResponseValidationHandler[T] { + return &ResponseValidationHandler[T]{ + nextHandler: nil, + } +} + +func (h *ResponseValidationHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + if h.nextHandler == nil { + err := errors.New("Handler chain terminated without terminating handler") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + resp, handlerError := h.nextHandler.Handle(request) + if handlerError != nil { + return nil, handlerError + } + + err := validation.ValidateData(resp.Data) + if err != nil { + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + return resp, nil +} + +func (h *ResponseValidationHandler[T]) SetNext(handler Handler[T]) { + h.nextHandler = handler +} diff --git a/internal/client/internal/clients/rest/handlers/retry_handler.go b/internal/client/internal/clients/rest/handlers/retry_handler.go new file mode 100644 index 0000000..c3dab5b --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/retry_handler.go @@ -0,0 +1,53 @@ +package handlers + +import ( + "errors" + "time" + + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +const ( + maxRetries = 3 + retryDelay = 150 * time.Millisecond +) + +type RetryHandler[T any] struct { + nextHandler Handler[T] +} + +func NewRetryHandler[T any]() *RetryHandler[T] { + return &RetryHandler[T]{ + nextHandler: nil, + } +} + +func (h *RetryHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + if h.nextHandler == nil { + err := errors.New("Handler chain terminated without terminating handler") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + var err *httptransport.ErrorResponse[T] + for tryCount := 0; tryCount < maxRetries; tryCount++ { + nextRequest := request.Clone() + + var resp *httptransport.Response[T] + resp, err = h.nextHandler.Handle(nextRequest) + if err != nil { + return nil, err + } + + if resp.StatusCode < 400 { + return resp, nil + } + + backoffDuration := time.Duration(tryCount) * retryDelay + time.Sleep(backoffDuration) + } + return nil, httptransport.NewErrorResponse[T](err, nil) +} + +func (h *RetryHandler[T]) SetNext(handler Handler[T]) { + h.nextHandler = handler +} diff --git a/internal/client/internal/clients/rest/handlers/terminating_handler.go b/internal/client/internal/clients/rest/handlers/terminating_handler.go new file mode 100644 index 0000000..cf4f0a9 --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/terminating_handler.go @@ -0,0 +1,48 @@ +package handlers + +import ( + "fmt" + "net/http" + "time" + + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +type TerminatingHandler[T any] struct { + httpClient *http.Client +} + +func NewTerminatingHandler[T any]() *TerminatingHandler[T] { + return &TerminatingHandler[T]{ + httpClient: &http.Client{Timeout: time.Second * 10}, + } +} + +func (h *TerminatingHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + requestClone := request.Clone() + req, err := requestClone.CreateHttpRequest() + if err != nil { + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + resp, err := h.httpClient.Do(req) + if err != nil { + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + transportResponse, responseErr := httptransport.NewResponse[T](resp) + if responseErr != nil { + return nil, httptransport.NewErrorResponse[T](responseErr, transportResponse) + } + + if transportResponse.StatusCode >= 400 { + err := fmt.Errorf("HTTP request failed with status code %d", transportResponse.StatusCode) + return nil, httptransport.NewErrorResponse[T](err, transportResponse) + } + + return transportResponse, nil +} + +func (h *TerminatingHandler[T]) SetNext(handler Handler[T]) { + fmt.Println("WARNING: SetNext should not be called on the terminating handler.") +} diff --git a/internal/client/internal/clients/rest/handlers/unmarshal_handler.go b/internal/client/internal/clients/rest/handlers/unmarshal_handler.go new file mode 100644 index 0000000..d90c92d --- /dev/null +++ b/internal/client/internal/clients/rest/handlers/unmarshal_handler.go @@ -0,0 +1,45 @@ +package handlers + +import ( + "errors" + + "github.com/go-provider-sdk/internal/clients/rest/httptransport" + "github.com/go-provider-sdk/internal/unmarshal" +) + +type UnmarshalHandler[T any] struct { + nextHandler Handler[T] +} + +func NewUnmarshalHandler[T any]() *UnmarshalHandler[T] { + return &UnmarshalHandler[T]{ + nextHandler: nil, + } +} + +func (h *UnmarshalHandler[T]) Handle(request httptransport.Request) (*httptransport.Response[T], *httptransport.ErrorResponse[T]) { + if h.nextHandler == nil { + err := errors.New("Handler chain terminated without terminating handler") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + resp, handlerError := h.nextHandler.Handle(request) + if handlerError != nil { + return nil, handlerError + } + + target := new(T) + err := unmarshal.Unmarshal(resp.Body, target) + if err != nil { + err := errors.New("failed to unmarshal response body into struct") + return nil, httptransport.NewErrorResponse[T](err, nil) + } + + resp.Data = *target + + return resp, nil +} + +func (h *UnmarshalHandler[T]) SetNext(handler Handler[T]) { + h.nextHandler = handler +} diff --git a/internal/client/internal/clients/rest/hooks/default_hook.go b/internal/client/internal/clients/rest/hooks/default_hook.go new file mode 100644 index 0000000..395574f --- /dev/null +++ b/internal/client/internal/clients/rest/hooks/default_hook.go @@ -0,0 +1,19 @@ +package hooks + +type DefaultHook struct{} + +func NewDefaultHook() Hook { + return &DefaultHook{} +} + +func (h *DefaultHook) BeforeRequest(req Request) Request { + return req +} + +func (h *DefaultHook) AfterResponse(req Request, resp Response) Response { + return resp +} + +func (h *DefaultHook) OnError(req Request, resp ErrorResponse) ErrorResponse { + return resp +} diff --git a/internal/client/internal/clients/rest/hooks/hook.go b/internal/client/internal/clients/rest/hooks/hook.go new file mode 100644 index 0000000..bf02a28 --- /dev/null +++ b/internal/client/internal/clients/rest/hooks/hook.go @@ -0,0 +1,46 @@ +package hooks + +type Hook interface { + BeforeRequest(req Request) Request + AfterResponse(req Request, resp Response) Response + OnError(req Request, resp ErrorResponse) ErrorResponse +} + +type Request interface { + GetMethod() string + SetMethod(method string) + GetBaseUrl() string + SetBaseUrl(baseUrl string) + GetPath() string + SetPath(path string) + GetPathParam(param string) string + SetPathParam(param string, value any) + GetHeader(header string) string + SetHeader(header string, value string) + GetQueryParam(header string) string + SetQueryParam(header string, value string) + GetOptions() any + SetOptions(options any) + GetBody() any + SetBody(body any) +} + +type Response interface { + GetStatusCode() int + SetStatusCode(statusCode int) + GetHeader(header string) string + SetHeader(header string, value string) + GetBody() []byte + SetBody(body []byte) +} + +type ErrorResponse interface { + Error() string + GetError() error + GetStatusCode() int + SetStatusCode(statusCode int) + GetHeader(header string) string + SetHeader(header string, value string) + GetBody() []byte + SetBody(body []byte) +} diff --git a/internal/client/internal/clients/rest/httptransport/error_response.go b/internal/client/internal/clients/rest/httptransport/error_response.go new file mode 100644 index 0000000..5d77509 --- /dev/null +++ b/internal/client/internal/clients/rest/httptransport/error_response.go @@ -0,0 +1,45 @@ +package httptransport + +import "fmt" + +type ErrorResponse[T any] struct { + Err error + IsHttpError bool + Response[T] +} + +func NewErrorResponse[T any](err error, resp *Response[T]) *ErrorResponse[T] { + if resp == nil { + return &ErrorResponse[T]{ + Err: err, + IsHttpError: false, + } + } + + return &ErrorResponse[T]{ + Err: err, + IsHttpError: true, + Response: *resp, + } +} + +func (r *ErrorResponse[T]) Clone() ErrorResponse[T] { + if r == nil { + return ErrorResponse[T]{} + } + + clone := *r + clone.Headers = make(map[string]string) + for header, value := range r.Headers { + clone.Headers[header] = value + } + return clone +} + +func (r *ErrorResponse[T]) Error() string { + return fmt.Sprintf("%s", r.Err) +} + +func (r *ErrorResponse[T]) GetError() error { + return r.Err +} diff --git a/internal/client/internal/clients/rest/httptransport/request.go b/internal/client/internal/clients/rest/httptransport/request.go new file mode 100644 index 0000000..64d914f --- /dev/null +++ b/internal/client/internal/clients/rest/httptransport/request.go @@ -0,0 +1,240 @@ +package httptransport + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "reflect" + "strings" + + "github.com/go-provider-sdk/internal/utils" + "github.com/go-provider-sdk/pkg/clientconfig" +) + +type paramMap struct { + Key string + Value string +} + +type Request struct { + Context context.Context + Method string + Path string + Headers map[string]string + QueryParams map[string]string + PathParams map[string]string + Options any + Body any + Config clientconfig.Config +} + +func NewRequest(ctx context.Context, method string, path string, config clientconfig.Config) Request { + return Request{ + Context: ctx, + Method: method, + Path: path, + Headers: make(map[string]string), + QueryParams: make(map[string]string), + PathParams: make(map[string]string), + Config: config, + } +} + +func (r *Request) Clone() Request { + if r == nil { + return Request{ + Headers: make(map[string]string), + QueryParams: make(map[string]string), + PathParams: make(map[string]string), + } + } + + clone := *r + clone.PathParams = utils.CloneMap(r.PathParams) + clone.Headers = utils.CloneMap(r.Headers) + clone.QueryParams = utils.CloneMap(r.QueryParams) + + return clone +} + +func (r *Request) GetMethod() string { + return r.Method +} + +func (r *Request) SetMethod(method string) { + r.Method = method +} + +func (r *Request) GetBaseUrl() string { + return *r.Config.BaseUrl +} + +func (r *Request) SetBaseUrl(baseUrl string) { + r.Config.SetBaseUrl(baseUrl) +} + +func (r *Request) GetPath() string { + return r.Path +} + +func (r *Request) SetPath(path string) { + r.Path = path +} + +func (r *Request) GetHeader(header string) string { + return r.Headers[header] +} + +func (r *Request) SetHeader(header string, value string) { + r.Headers[header] = value +} + +func (r *Request) GetPathParam(param string) string { + return r.PathParams[param] +} + +func (r *Request) SetPathParam(param string, value any) { + r.PathParams[param] = fmt.Sprintf("%v", value) +} + +func (r *Request) GetQueryParam(header string) string { + return r.QueryParams[header] +} + +func (r *Request) SetQueryParam(header string, value string) { + r.QueryParams[header] = value +} + +func (r *Request) GetOptions() any { + return r.Options +} + +func (r *Request) SetOptions(options any) { + r.Options = options +} + +func (r *Request) GetBody() any { + return r.Body +} + +func (r *Request) SetBody(body any) { + r.Body = body +} + +func (r *Request) GetContext() context.Context { + return r.Context +} + +func (r *Request) SetContext(ctx context.Context) { + r.Context = ctx +} + +func (r *Request) CreateHttpRequest() (*http.Request, error) { + requestUrl := r.getRequestUrl() + + requestBody, err := r.bodyToBytesReader() + if err != nil { + return nil, err + } + + var httpRequest *http.Request + if requestBody == nil { + httpRequest, err = http.NewRequestWithContext(r.Context, r.Method, requestUrl, nil) + } else { + httpRequest, err = http.NewRequestWithContext(r.Context, r.Method, requestUrl, requestBody) + } + + httpRequest.Header = r.getRequestHeaders() + + return httpRequest, err +} + +func (r *Request) getRequestUrl() string { + requestPath := r.Path + for paramName, paramValue := range r.PathParams { + placeholder := "{" + paramName + "}" + requestPath = strings.ReplaceAll(requestPath, placeholder, url.PathEscape(paramValue)) + } + + requestOptions := "" + params := r.getRequestQueryParams() + if len(params) > 0 { + requestOptions = fmt.Sprintf("?%s", params.Encode()) + } + + return *r.Config.BaseUrl + requestPath + requestOptions +} + +func (r *Request) bodyToBytesReader() (*bytes.Reader, error) { + if r.Body == nil { + return nil, nil + } + + marshalledBody, err := json.Marshal(r.Body) + if err != nil { + return nil, err + } + reqBody := bytes.NewReader(marshalledBody) + + return reqBody, nil +} + +func (r *Request) getRequestQueryParams() url.Values { + params := url.Values{} + for key, value := range r.QueryParams { + params.Add(key, value) + } + + for _, p := range tagsToMap("queryParam", r.Options) { + params.Add(p.Key, p.Value) + } + + return params +} + +func (r *Request) getRequestHeaders() http.Header { + headers := http.Header{} + for key, value := range r.Headers { + headers.Add(key, value) + } + + for _, p := range tagsToMap("headerParam", r.Options) { + headers.Add(p.Key, p.Value) + } + + return headers +} + +func tagsToMap(tag string, obj any) []paramMap { + tagMap := make([]paramMap, 0) + + if obj == nil { + return tagMap + } + + values := utils.GetReflectValue(reflect.ValueOf(obj)) + for i := 0; i < values.NumField(); i++ { + key, found := values.Type().Field(i).Tag.Lookup(tag) + if !found || values.Field(i).Type().Kind() == reflect.Pointer && values.Field(i).IsNil() { + continue + } + + field := utils.GetReflectValue(values.Field(i)) + + fieldKind := utils.GetReflectKind(field.Type()) + if fieldKind == reflect.Array || fieldKind == reflect.Slice { + for j := 0; j < field.Len(); j++ { + p := paramMap{Key: key, Value: fmt.Sprint(field.Index(j))} + tagMap = append(tagMap, p) + } + } else { + p := paramMap{Key: key, Value: fmt.Sprint(field)} + tagMap = append(tagMap, p) + } + } + + return tagMap +} diff --git a/internal/client/internal/clients/rest/httptransport/response.go b/internal/client/internal/clients/rest/httptransport/response.go new file mode 100644 index 0000000..6cb54df --- /dev/null +++ b/internal/client/internal/clients/rest/httptransport/response.go @@ -0,0 +1,78 @@ +package httptransport + +import ( + "io" + "net/http" +) + +type Response[T any] struct { + StatusCode int + Headers map[string]string + Body []byte + Data T +} + +func (r *Response[T]) Clone() Response[T] { + if r == nil { + return Response[T]{ + Headers: make(map[string]string), + } + } + + clone := *r + clone.Headers = make(map[string]string) + for header, value := range r.Headers { + clone.Headers[header] = value + } + return clone +} + +func NewResponse[T any](resp *http.Response) (*Response[T], error) { + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, NewErrorResponse[T](err, nil) + } + + responseHeaders := make(map[string]string) + for key := range resp.Header { + responseHeaders[key] = resp.Header.Get(key) + } + + placeholderData := new(T) + return &Response[T]{ + StatusCode: resp.StatusCode, + Headers: responseHeaders, + Body: body, + Data: *placeholderData, + }, nil +} + +func (r *Response[T]) GetStatusCode() int { + return r.StatusCode +} + +func (r *Response[T]) SetStatusCode(statusCode int) { + r.StatusCode = statusCode +} + +func (r *Response[T]) GetHeaders() map[string]string { + return r.Headers +} + +func (r *Response[T]) GetHeader(header string) string { + return r.Headers[header] +} + +func (r *Response[T]) SetHeader(header string, value string) { + r.Headers[header] = value +} + +func (r *Response[T]) GetBody() []byte { + return r.Body +} + +func (r *Response[T]) SetBody(body []byte) { + r.Body = body +} diff --git a/internal/client/internal/configmanager/config_manager.go b/internal/client/internal/configmanager/config_manager.go new file mode 100644 index 0000000..95c4675 --- /dev/null +++ b/internal/client/internal/configmanager/config_manager.go @@ -0,0 +1,54 @@ +package configmanager + +import "github.com/go-provider-sdk/pkg/clientconfig" + +type ConfigManager struct { + GrantKits clientconfig.Config + Identities clientconfig.Config + Demo clientconfig.Config +} + +func NewConfigManager(config clientconfig.Config) *ConfigManager { + return &ConfigManager{ + GrantKits: config, + Identities: config, + Demo: config, + } +} + +func (c *ConfigManager) SetBaseUrl(baseUrl string) { + c.GrantKits.SetBaseUrl(baseUrl) + c.Identities.SetBaseUrl(baseUrl) + c.Demo.SetBaseUrl(baseUrl) +} + +func (c *ConfigManager) SetAccessToken(accessToken string) { + c.GrantKits.SetAccessToken(accessToken) + c.Identities.SetAccessToken(accessToken) + c.Demo.SetAccessToken(accessToken) +} + +func (c *ConfigManager) UpdateAccessToken(originalValue string, newValue string) { + + if c.GrantKits.AccessToken != nil && *c.GrantKits.AccessToken == originalValue { + c.GrantKits.SetAccessToken(newValue) + } + + if c.Identities.AccessToken != nil && *c.Identities.AccessToken == originalValue { + c.Identities.SetAccessToken(newValue) + } + + if c.Demo.AccessToken != nil && *c.Demo.AccessToken == originalValue { + c.Demo.SetAccessToken(newValue) + } +} + +func (c *ConfigManager) GetGrantKits() *clientconfig.Config { + return &c.GrantKits +} +func (c *ConfigManager) GetIdentities() *clientconfig.Config { + return &c.Identities +} +func (c *ConfigManager) GetDemo() *clientconfig.Config { + return &c.Demo +} diff --git a/internal/client/internal/marshal/from_complex_object.go b/internal/client/internal/marshal/from_complex_object.go new file mode 100644 index 0000000..eef63c3 --- /dev/null +++ b/internal/client/internal/marshal/from_complex_object.go @@ -0,0 +1,22 @@ +package marshal + +import ( + "encoding/json" + "errors" + "reflect" + + "github.com/go-provider-sdk/internal/utils" +) + +func FromComplexObject(obj any) ([]byte, error) { + types := utils.GetReflectType(reflect.TypeOf(obj)) + values := utils.GetReflectValue(reflect.ValueOf(obj)) + + for i := 0; i < types.NumField(); i++ { + if !values.Field(i).IsNil() { + return json.Marshal(values.Field(i).Interface()) + } + } + + return nil, errors.New("cannot marshal complex object, no non-nil fields found") +} diff --git a/internal/client/internal/unmarshal/to_complex_object.go b/internal/client/internal/unmarshal/to_complex_object.go new file mode 100644 index 0000000..a78f264 --- /dev/null +++ b/internal/client/internal/unmarshal/to_complex_object.go @@ -0,0 +1,276 @@ +package unmarshal + +import ( + "encoding/json" + "errors" + "fmt" + "reflect" + "strconv" + + "github.com/go-provider-sdk/internal/utils" + "github.com/go-provider-sdk/internal/validation" +) + +type candidate struct { + obj any + valid bool + requiredCount int + optionalCount int + kind reflect.Kind +} + +func ToComplexObject[T any](data []byte, result *T) error { + err := unmarshalIntoProps(data, result) + if err != nil { + return err + } + + candidates := createCandidatesFromProps(result) + chosenCandidateIndex := chooseCandidateIndex(candidates) + if chosenCandidateIndex == -1 { + return errors.New("cannot unmarshal response, no valid candidate found") + } + removeOtherCandidates(result, chosenCandidateIndex) + + return nil +} + +// Try to Unmarshal the input data into the properties of a given struct. +func unmarshalIntoProps(data []byte, obj any) error { + types := reflect.TypeOf(obj).Elem() + values := reflect.ValueOf(obj).Elem() + + for i := 0; i < types.NumField(); i++ { + fieldType := types.Field(i) + kind := utils.GetReflectKind(fieldType.Type) + if kind == reflect.Struct || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map { + unmarshalledValue := reflect.New(fieldType.Type) + err := json.Unmarshal(data, unmarshalledValue.Interface()) + if err != nil { + continue + } + + value := unmarshalledValue.Elem() + values.Field(i).Set(value) + } else if kind == reflect.String { + strValue := string(data) + values.Field(i).Set(reflect.ValueOf(&strValue)) + } else if kind == reflect.Float32 || kind == reflect.Float64 { + value, err := strconv.ParseFloat(string(data), 64) + if err == nil { + values.Field(i).Set(reflect.ValueOf(&value)) + } + } else if kind == reflect.Int || kind == reflect.Int8 || kind == reflect.Int16 || kind == reflect.Int32 || kind == reflect.Int64 { + value, err := strconv.ParseInt(string(data), 10, 64) + if err == nil { + values.Field(i).Set(reflect.ValueOf(&value)) + } + } else if kind == reflect.Bool { + value, err := strconv.ParseBool(string(data)) + if err == nil { + values.Field(i).Set(reflect.ValueOf(&value)) + } + } else if kind == reflect.Interface { + values.Field(i).Set(reflect.ValueOf(string(data))) + } else { + return fmt.Errorf("cannot unmarshal response, unsupported type: %s", kind) + } + } + + return nil +} + +func createCandidatesFromProps(obj any) []candidate { + values := utils.GetReflectValue(reflect.ValueOf(obj)) + types := utils.GetReflectType(reflect.TypeOf(obj)) + + candidates := make([]candidate, 0) + for i := 0; i < types.NumField(); i++ { + fieldValue := values.Field(i) + kind := utils.GetReflectKind(types.Field(i).Type) + + var c candidate + if fieldValue.IsNil() { + c = candidate{ + obj: nil, + valid: false, + requiredCount: 0, + optionalCount: 0, + kind: kind, + } + } else if kind == reflect.Struct { + value := fieldValue.Interface() + c = candidate{ + obj: value, + valid: isValid(value), + requiredCount: countFields(value, validation.IsRequiredField), + optionalCount: countFields(value, validation.IsOptionalField), + kind: kind, + } + } else if kind == reflect.Array || kind == reflect.Slice { + value := fieldValue.Interface() + c = candidate{ + obj: value, + valid: isValid(value), + requiredCount: countArrayFields(value, validation.IsRequiredField), + optionalCount: countArrayFields(value, validation.IsOptionalField), + kind: kind, + } + } else { + value := fieldValue.Interface() + c = candidate{ + obj: value, + valid: true, + requiredCount: 0, + optionalCount: 0, + kind: kind, + } + } + + candidates = append(candidates, c) + } + + return candidates +} + +func countFields(c any, isFieldRequiredOrOptional func(reflect.StructField) bool) int { + values := utils.GetReflectValue(reflect.ValueOf(c)) + types := utils.GetReflectType(reflect.TypeOf(c)) + + if isPrimitive(utils.GetReflectKind(types)) { + return 0 + } + + count := 0 + for i := 0; i < types.NumField(); i++ { + fieldValue := values.Field(i) + fieldType := types.Field(i) + + if fieldValue.IsNil() { + continue + } + + if isFieldRequiredOrOptional(fieldType) { + count++ + } + + kind := utils.GetReflectKind(fieldType.Type) + if kind == reflect.Struct || kind == reflect.Array || kind == reflect.Slice { + count += countFields(fieldValue.Interface(), isFieldRequiredOrOptional) + } + } + + return count +} + +func countArrayFields(candidates any, isFieldRequiredOrOptional func(reflect.StructField) bool) int { + count := 0 + values := utils.GetReflectValue(reflect.ValueOf(candidates)) + for i := 0; i < values.Len(); i++ { + candidate := values.Index(i).Interface() + count += countFields(candidate, isFieldRequiredOrOptional) + } + + return count +} + +func isValid(candidate any) bool { + err := validation.ValidateData(candidate) + return err == nil +} + +func chooseCandidateIndex(candidates []candidate) int { + chosenCandidateIndex := chooseNonPrimitiveCandidate(candidates) + + if chosenCandidateIndex == -1 { + chosenCandidateIndex = choosePrimitiveCandidate(candidates) + } + + return chosenCandidateIndex +} + +func chooseNonPrimitiveCandidate(candidates []candidate) int { + chosenCandidateIndex := -1 + chosenCandidateRequiredCount := -1 + chosenCandidateOptionalCount := -1 + + for i, candidate := range candidates { + if isBetterCandidate(candidate, chosenCandidateRequiredCount, chosenCandidateOptionalCount) { + chosenCandidateIndex = i + chosenCandidateRequiredCount = candidate.requiredCount + chosenCandidateOptionalCount = candidate.optionalCount + } + } + + return chosenCandidateIndex +} + +func isBetterCandidate(c candidate, chosenCandidateRequiredCount int, chosenCandidateOptionalCount int) bool { + if !c.valid || isPrimitive(c.kind) { + return false + } + + if c.requiredCount > chosenCandidateRequiredCount { + return true + } + + if c.requiredCount == chosenCandidateRequiredCount && c.optionalCount > chosenCandidateOptionalCount { + return true + } + + return false +} + +func choosePrimitiveCandidate(candidates []candidate) int { + predicates := []func(kind reflect.Kind) bool{isBool, isInteger, isFloat, isString} + + for _, predicate := range predicates { + chosenCandidateIndex := findFirstNonNil(candidates, predicate) + if chosenCandidateIndex != -1 { + return chosenCandidateIndex + } + } + + return -1 +} + +func removeOtherCandidates(obj any, chosenCandidateIndex int) { + values := utils.GetReflectValue(reflect.ValueOf(obj)) + types := utils.GetReflectType(reflect.TypeOf(obj)) + + for i := 0; i < types.NumField(); i++ { + if i != chosenCandidateIndex { + fieldValue := values.Field(i) + fieldValue.Set(reflect.Zero(fieldValue.Type())) + } + } +} + +func findFirstNonNil(candidates []candidate, predicate func(kind reflect.Kind) bool) int { + for i, c := range candidates { + if c.obj != nil && predicate(c.kind) { + return i + } + } + return -1 +} + +func isPrimitive(kind reflect.Kind) bool { + return isInteger(kind) || isString(kind) || isBool(kind) || isFloat(kind) +} + +func isInteger(kind reflect.Kind) bool { + return kind == reflect.Int || kind == reflect.Int8 || kind == reflect.Int16 || kind == reflect.Int32 || kind == reflect.Int64 +} + +func isFloat(kind reflect.Kind) bool { + return kind == reflect.Float32 || kind == reflect.Float64 +} + +func isBool(kind reflect.Kind) bool { + return kind == reflect.Bool +} + +func isString(kind reflect.Kind) bool { + return kind == reflect.String +} diff --git a/internal/client/internal/unmarshal/to_object.go b/internal/client/internal/unmarshal/to_object.go new file mode 100644 index 0000000..040b0bc --- /dev/null +++ b/internal/client/internal/unmarshal/to_object.go @@ -0,0 +1,13 @@ +package unmarshal + +import ( + "encoding/json" +) + +func ToObject(source []byte, target any) error { + err := json.Unmarshal(source, target) + if err != nil { + return err + } + return nil +} diff --git a/internal/client/internal/unmarshal/to_primitive.go b/internal/client/internal/unmarshal/to_primitive.go new file mode 100644 index 0000000..42a74c2 --- /dev/null +++ b/internal/client/internal/unmarshal/to_primitive.go @@ -0,0 +1,44 @@ +package unmarshal + +import ( + "reflect" + "strconv" +) + +func ToString(source []byte, target reflect.Value) error { + target.Elem().SetString(string(source)) + return nil +} + +func ToInt(source []byte, target reflect.Value) error { + intBody, err := strconv.ParseInt(string(source), 10, 64) + if err != nil { + return err + } + + target.Elem().SetInt(intBody) + + return nil +} + +func ToFloat(source []byte, target reflect.Value) error { + floatBody, err := strconv.ParseFloat(string(source), 64) + if err != nil { + return err + } + + target.Elem().SetFloat(floatBody) + + return nil +} + +func ToBool(source []byte, target reflect.Value) error { + boolBody, err := strconv.ParseBool(string(source)) + if err != nil { + return err + } + + target.Elem().SetBool(boolBody) + + return nil +} diff --git a/internal/client/internal/unmarshal/unmarshal.go b/internal/client/internal/unmarshal/unmarshal.go new file mode 100644 index 0000000..268a1cf --- /dev/null +++ b/internal/client/internal/unmarshal/unmarshal.go @@ -0,0 +1,63 @@ +package unmarshal + +import ( + "fmt" + "reflect" + + "github.com/go-provider-sdk/internal/utils" +) + +func Unmarshal(source []byte, target any) error { + + targetValue := reflect.ValueOf(target) + if targetValue.Kind() != reflect.Ptr || targetValue.IsNil() { + return fmt.Errorf("target must be a non-nil pointer") + } + + if isComplexObject(target) || isObject(target) || isArray(target) { + return ToObject(source, target) + } else if isString(targetValue.Elem().Kind()) { + return ToString(source, targetValue) + } else if isInteger(targetValue.Elem().Kind()) { + return ToInt(source, targetValue) + } else if isFloat(targetValue.Elem().Kind()) { + return ToFloat(source, targetValue) + } else if isBool(targetValue.Elem().Kind()) { + return ToBool(source, targetValue) + } + + return nil +} + +func isArray(target any) bool { + targetType := reflect.TypeOf(target) + kind := utils.GetReflectKind(targetType) + return kind == reflect.Array || kind == reflect.Slice +} + +func isObject(target any) bool { + targetType := reflect.TypeOf(target) + return utils.GetReflectKind(targetType) == reflect.Struct +} + +func isComplexObject(target any) bool { + targetType := reflect.TypeOf(target) + if utils.GetReflectKind(targetType) != reflect.Struct { + return false + } + + allFieldsAreOneOf := true + + structValue := utils.GetReflectValue(reflect.ValueOf(target)) + for i := 0; i < structValue.NumField(); i++ { + field := structValue.Type().Field(i) + allFieldsAreOneOf = isOneOfField(field) && allFieldsAreOneOf + } + + return allFieldsAreOneOf +} + +func isOneOfField(field reflect.StructField) bool { + _, found := field.Tag.Lookup("oneof") + return found +} diff --git a/internal/client/internal/utils/utils.go b/internal/client/internal/utils/utils.go new file mode 100644 index 0000000..0766a7a --- /dev/null +++ b/internal/client/internal/utils/utils.go @@ -0,0 +1,36 @@ +package utils + +import "reflect" + +func CloneMap[T any](sourceMap map[string]T) map[string]T { + newMap := make(map[string]T) + for key, value := range sourceMap { + newMap[key] = value + } + + return newMap +} + +func GetReflectValue(fieldValue reflect.Value) reflect.Value { + if fieldValue.Kind() == reflect.Pointer { + return fieldValue.Elem() + } else { + return fieldValue + } +} + +func GetReflectType(fieldType reflect.Type) reflect.Type { + if fieldType.Kind() == reflect.Ptr { + return fieldType.Elem() + } else { + return fieldType + } +} + +func GetReflectKind(fieldType reflect.Type) reflect.Kind { + if fieldType.Kind() == reflect.Pointer { + return fieldType.Elem().Kind() + } else { + return fieldType.Kind() + } +} diff --git a/internal/client/internal/validation/validate_required.go b/internal/client/internal/validation/validate_required.go new file mode 100644 index 0000000..7de2eab --- /dev/null +++ b/internal/client/internal/validation/validate_required.go @@ -0,0 +1,24 @@ +package validation + +import ( + "fmt" + "reflect" +) + +func validateRequired(fieldValue reflect.Value, fieldType reflect.StructField) error { + if IsRequiredField(fieldType) && fieldValue.IsNil() { + return fmt.Errorf("field %s is required", fieldType.Name) + } + + return nil +} + +func IsRequiredField(fieldType reflect.StructField) bool { + required, found := fieldType.Tag.Lookup("required") + return found && required == "true" +} + +func IsOptionalField(fieldType reflect.StructField) bool { + required, found := fieldType.Tag.Lookup("required") + return !found || required == "" || required == "false" +} diff --git a/internal/client/internal/validation/validation.go b/internal/client/internal/validation/validation.go new file mode 100644 index 0000000..c378d8e --- /dev/null +++ b/internal/client/internal/validation/validation.go @@ -0,0 +1,80 @@ +package validation + +import ( + "reflect" + + "github.com/go-provider-sdk/internal/utils" +) + +type validatorFunc = func(fieldValue reflect.Value, fieldType reflect.StructField) error + +func ValidateData(data any) error { + if data == nil { + return nil + } + + dataType := reflect.TypeOf(data) + dataValue := reflect.ValueOf(data) + if utils.GetReflectKind(dataType) == reflect.Struct { + return validateStruct(data) + } else if dataType.Kind() == reflect.Array || dataType.Kind() == reflect.Slice { + return validateArray(dataValue) + } + + return nil +} + +func validateStruct(data any) error { + structValue := utils.GetReflectValue(reflect.ValueOf(data)) + for i := 0; i < structValue.NumField(); i++ { + fieldValue := structValue.Field(i) + fieldType := structValue.Type().Field(i) + + err := validateField(fieldValue, fieldType) + if err != nil { + return err + } + + if fieldValue.IsNil() { + continue + } + + kind := utils.GetReflectKind(fieldType.Type) + if kind == reflect.Struct || kind == reflect.Array || kind == reflect.Slice { + err := ValidateData(fieldValue.Interface()) + if err != nil { + return err + } + } + } + + return nil +} + +func validateArray(value reflect.Value) error { + arrayValue := utils.GetReflectValue(value) + for j := 0; j < arrayValue.Len(); j++ { + err := ValidateData(arrayValue.Index(j).Interface()) + if err != nil { + return err + } + } + + return nil +} + +func validateField(fieldValue reflect.Value, fieldType reflect.StructField) error { + validators := getValidators(fieldType) + for _, validator := range validators { + err := validator(fieldValue, fieldType) + if err != nil { + return err + } + } + + return nil +} + +func getValidators(fieldType reflect.StructField) []validatorFunc { + return []validatorFunc{validateRequired} +} diff --git a/internal/client/pkg/client/client.go b/internal/client/pkg/client/client.go new file mode 100644 index 0000000..45a51c8 --- /dev/null +++ b/internal/client/pkg/client/client.go @@ -0,0 +1,36 @@ +package client + +import ( + "github.com/go-provider-sdk/internal/configmanager" + "github.com/go-provider-sdk/pkg/clientconfig" + "github.com/go-provider-sdk/pkg/demo" + "github.com/go-provider-sdk/pkg/grantkits" + "github.com/go-provider-sdk/pkg/identities" +) + +type Client struct { + GrantKits *grantkits.GrantKitsService + Identities *identities.IdentitiesService + Demo *demo.DemoService + manager *configmanager.ConfigManager +} + +func NewClient(config clientconfig.Config) *Client { + manager := configmanager.NewConfigManager(config) + return &Client{ + GrantKits: grantkits.NewGrantKitsService(manager), + Identities: identities.NewIdentitiesService(manager), + Demo: demo.NewDemoService(manager), + manager: manager, + } +} + +func (c *Client) SetBaseUrl(baseUrl string) { + c.manager.SetBaseUrl(baseUrl) +} + +func (c *Client) SetAccessToken(accessToken string) { + c.manager.SetAccessToken(accessToken) +} + +// c029837e0e474b76bc487506e8799df5e3335891efe4fb02bda7a1441840310c diff --git a/internal/client/pkg/clientconfig/config.go b/internal/client/pkg/clientconfig/config.go new file mode 100644 index 0000000..8c74909 --- /dev/null +++ b/internal/client/pkg/clientconfig/config.go @@ -0,0 +1,23 @@ +package clientconfig + +type Config struct { + BaseUrl *string + AccessToken *string +} + +func NewConfig() Config { + baseUrl := "https://api.abbey.io/v1" + newConfig := Config{ + BaseUrl: &baseUrl, + } + + return newConfig +} + +func (c *Config) SetBaseUrl(baseUrl string) { + c.BaseUrl = &baseUrl +} + +func (c *Config) SetAccessToken(accessToken string) { + c.AccessToken = &accessToken +} diff --git a/internal/client/pkg/demo/demo.go b/internal/client/pkg/demo/demo.go new file mode 100644 index 0000000..5d0449f --- /dev/null +++ b/internal/client/pkg/demo/demo.go @@ -0,0 +1,52 @@ +package demo + +type Demo struct { + Id *int64 `json:"id,omitempty"` + UserId *string `json:"user_id,omitempty"` + CreatedAt *string `json:"created_at,omitempty"` + UpdatedAt *string `json:"updated_at,omitempty"` +} + +func (d *Demo) SetId(id int64) { + d.Id = &id +} + +func (d *Demo) GetId() *int64 { + if d == nil { + return nil + } + return d.Id +} + +func (d *Demo) SetUserId(userId string) { + d.UserId = &userId +} + +func (d *Demo) GetUserId() *string { + if d == nil { + return nil + } + return d.UserId +} + +func (d *Demo) SetCreatedAt(createdAt string) { + d.CreatedAt = &createdAt +} + +func (d *Demo) GetCreatedAt() *string { + if d == nil { + return nil + } + return d.CreatedAt +} + +func (d *Demo) SetUpdatedAt(updatedAt string) { + d.UpdatedAt = &updatedAt +} + +func (d *Demo) GetUpdatedAt() *string { + if d == nil { + return nil + } + return d.UpdatedAt +} diff --git a/internal/client/pkg/demo/demo_params.go b/internal/client/pkg/demo/demo_params.go new file mode 100644 index 0000000..bc4925d --- /dev/null +++ b/internal/client/pkg/demo/demo_params.go @@ -0,0 +1,34 @@ +package demo + +type DemoParams struct { + Permission *Permission `json:"permission,omitempty" required:"true"` + Email *string `json:"email,omitempty" required:"true"` +} + +func (d *DemoParams) SetPermission(permission Permission) { + d.Permission = &permission +} + +func (d *DemoParams) GetPermission() *Permission { + if d == nil { + return nil + } + return d.Permission +} + +func (d *DemoParams) SetEmail(email string) { + d.Email = &email +} + +func (d *DemoParams) GetEmail() *string { + if d == nil { + return nil + } + return d.Email +} + +type Permission string + +const ( + PERMISSION_READ_WRITE Permission = "read_write" +) diff --git a/internal/client/pkg/demo/demo_service.go b/internal/client/pkg/demo/demo_service.go new file mode 100644 index 0000000..2065a47 --- /dev/null +++ b/internal/client/pkg/demo/demo_service.go @@ -0,0 +1,88 @@ +package demo + +import ( + "context" + restClient "github.com/go-provider-sdk/internal/clients/rest" + "github.com/go-provider-sdk/internal/clients/rest/httptransport" + "github.com/go-provider-sdk/internal/configmanager" + "github.com/go-provider-sdk/pkg/clientconfig" + "github.com/go-provider-sdk/pkg/shared" +) + +type DemoService struct { + manager *configmanager.ConfigManager +} + +func NewDemoService(manager *configmanager.ConfigManager) *DemoService { + return &DemoService{ + manager: manager, + } +} + +func (api *DemoService) getConfig() *clientconfig.Config { + return api.manager.GetDemo() +} + +func (api *DemoService) SetBaseUrl(baseUrl string) { + config := api.getConfig() + config.SetBaseUrl(baseUrl) +} + +func (api *DemoService) SetAccessToken(accessToken string) { + config := api.getConfig() + config.SetAccessToken(accessToken) +} + +// Get the demo response +func (api *DemoService) GetDemo(ctx context.Context, params GetDemoRequestParams) (*shared.ClientResponse[Demo], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[Demo](config) + + request := httptransport.NewRequest(ctx, "GET", "/demo", config) + + request.Options = params + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[Demo](err) + } + + return shared.NewClientResponse[Demo](resp), nil +} + +// Creates a new Demo access +func (api *DemoService) CreateDemo(ctx context.Context, demoParams DemoParams) (*shared.ClientResponse[Demo], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[Demo](config) + + request := httptransport.NewRequest(ctx, "POST", "/demo", config) + + request.Body = demoParams + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[Demo](err) + } + + return shared.NewClientResponse[Demo](resp), nil +} + +// Deletes the Demo access +func (api *DemoService) DeleteDemo(ctx context.Context, demoParams DemoParams) (*shared.ClientResponse[any], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[any](config) + + request := httptransport.NewRequest(ctx, "DELETE", "/demo", config) + + request.Body = demoParams + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[any](err) + } + + return shared.NewClientResponse[any](resp), nil +} diff --git a/internal/client/pkg/demo/request_params.go b/internal/client/pkg/demo/request_params.go new file mode 100644 index 0000000..858777c --- /dev/null +++ b/internal/client/pkg/demo/request_params.go @@ -0,0 +1,9 @@ +package demo + +type GetDemoRequestParams struct { + Email *string `queryParam:"email" required:"true"` +} + +func (params *GetDemoRequestParams) SetEmail(email string) { + params.Email = &email +} diff --git a/internal/client/pkg/grantkits/grant.go b/internal/client/pkg/grantkits/grant.go new file mode 100644 index 0000000..ef55c19 --- /dev/null +++ b/internal/client/pkg/grantkits/grant.go @@ -0,0 +1,112 @@ +package grantkits + +type Grant struct { + Id *string `json:"id,omitempty" required:"true"` + GrantKitId *string `json:"grant_kit_id,omitempty" required:"true"` + GrantKitVersionId *string `json:"grant_kit_version_id,omitempty" required:"true"` + UserId *string `json:"user_id,omitempty" required:"true"` + RequestId *string `json:"request_id,omitempty" required:"true"` + OrganizationId *string `json:"organization_id,omitempty" required:"true"` + Deleted *bool `json:"deleted,omitempty" required:"true"` + CreatedAt *string `json:"created_at,omitempty" required:"true"` + UpdatedAt *string `json:"updated_at,omitempty" required:"true"` +} + +func (g *Grant) SetId(id string) { + g.Id = &id +} + +func (g *Grant) GetId() *string { + if g == nil { + return nil + } + return g.Id +} + +func (g *Grant) SetGrantKitId(grantKitId string) { + g.GrantKitId = &grantKitId +} + +func (g *Grant) GetGrantKitId() *string { + if g == nil { + return nil + } + return g.GrantKitId +} + +func (g *Grant) SetGrantKitVersionId(grantKitVersionId string) { + g.GrantKitVersionId = &grantKitVersionId +} + +func (g *Grant) GetGrantKitVersionId() *string { + if g == nil { + return nil + } + return g.GrantKitVersionId +} + +func (g *Grant) SetUserId(userId string) { + g.UserId = &userId +} + +func (g *Grant) GetUserId() *string { + if g == nil { + return nil + } + return g.UserId +} + +func (g *Grant) SetRequestId(requestId string) { + g.RequestId = &requestId +} + +func (g *Grant) GetRequestId() *string { + if g == nil { + return nil + } + return g.RequestId +} + +func (g *Grant) SetOrganizationId(organizationId string) { + g.OrganizationId = &organizationId +} + +func (g *Grant) GetOrganizationId() *string { + if g == nil { + return nil + } + return g.OrganizationId +} + +func (g *Grant) SetDeleted(deleted bool) { + g.Deleted = &deleted +} + +func (g *Grant) GetDeleted() *bool { + if g == nil { + return nil + } + return g.Deleted +} + +func (g *Grant) SetCreatedAt(createdAt string) { + g.CreatedAt = &createdAt +} + +func (g *Grant) GetCreatedAt() *string { + if g == nil { + return nil + } + return g.CreatedAt +} + +func (g *Grant) SetUpdatedAt(updatedAt string) { + g.UpdatedAt = &updatedAt +} + +func (g *Grant) GetUpdatedAt() *string { + if g == nil { + return nil + } + return g.UpdatedAt +} diff --git a/internal/client/pkg/grantkits/grant_kit.go b/internal/client/pkg/grantkits/grant_kit.go new file mode 100644 index 0000000..c81c3ca --- /dev/null +++ b/internal/client/pkg/grantkits/grant_kit.go @@ -0,0 +1,160 @@ +package grantkits + +type GrantKit struct { + Id *string `json:"id,omitempty" required:"true"` + Name *string `json:"name,omitempty" required:"true"` + CurrentVersionId *string `json:"current_version_id,omitempty" required:"true"` + Description *string `json:"description,omitempty" required:"true"` + MaxGrantDurationInSec *float64 `json:"max_grant_duration_in_sec,omitempty"` + Workflow *GrantWorkflow `json:"workflow,omitempty"` + Policies []Policy `json:"policies,omitempty"` + Output *Output `json:"output,omitempty" required:"true"` + Grants []Grant `json:"grants,omitempty" required:"true"` + ResourceType *string `json:"resource_type,omitempty" required:"true"` + Requests []Request `json:"requests,omitempty" required:"true"` + CreatedAt *string `json:"created_at,omitempty" required:"true"` + UpdatedAt *string `json:"updated_at,omitempty" required:"true"` +} + +func (g *GrantKit) SetId(id string) { + g.Id = &id +} + +func (g *GrantKit) GetId() *string { + if g == nil { + return nil + } + return g.Id +} + +func (g *GrantKit) SetName(name string) { + g.Name = &name +} + +func (g *GrantKit) GetName() *string { + if g == nil { + return nil + } + return g.Name +} + +func (g *GrantKit) SetCurrentVersionId(currentVersionId string) { + g.CurrentVersionId = ¤tVersionId +} + +func (g *GrantKit) GetCurrentVersionId() *string { + if g == nil { + return nil + } + return g.CurrentVersionId +} + +func (g *GrantKit) SetDescription(description string) { + g.Description = &description +} + +func (g *GrantKit) GetDescription() *string { + if g == nil { + return nil + } + return g.Description +} + +func (g *GrantKit) SetMaxGrantDurationInSec(maxGrantDurationInSec float64) { + g.MaxGrantDurationInSec = &maxGrantDurationInSec +} + +func (g *GrantKit) GetMaxGrantDurationInSec() *float64 { + if g == nil { + return nil + } + return g.MaxGrantDurationInSec +} + +func (g *GrantKit) SetWorkflow(workflow GrantWorkflow) { + g.Workflow = &workflow +} + +func (g *GrantKit) GetWorkflow() *GrantWorkflow { + if g == nil { + return nil + } + return g.Workflow +} + +func (g *GrantKit) SetPolicies(policies []Policy) { + g.Policies = policies +} + +func (g *GrantKit) GetPolicies() []Policy { + if g == nil { + return nil + } + return g.Policies +} + +func (g *GrantKit) SetOutput(output Output) { + g.Output = &output +} + +func (g *GrantKit) GetOutput() *Output { + if g == nil { + return nil + } + return g.Output +} + +func (g *GrantKit) SetGrants(grants []Grant) { + g.Grants = grants +} + +func (g *GrantKit) GetGrants() []Grant { + if g == nil { + return nil + } + return g.Grants +} + +func (g *GrantKit) SetResourceType(resourceType string) { + g.ResourceType = &resourceType +} + +func (g *GrantKit) GetResourceType() *string { + if g == nil { + return nil + } + return g.ResourceType +} + +func (g *GrantKit) SetRequests(requests []Request) { + g.Requests = requests +} + +func (g *GrantKit) GetRequests() []Request { + if g == nil { + return nil + } + return g.Requests +} + +func (g *GrantKit) SetCreatedAt(createdAt string) { + g.CreatedAt = &createdAt +} + +func (g *GrantKit) GetCreatedAt() *string { + if g == nil { + return nil + } + return g.CreatedAt +} + +func (g *GrantKit) SetUpdatedAt(updatedAt string) { + g.UpdatedAt = &updatedAt +} + +func (g *GrantKit) GetUpdatedAt() *string { + if g == nil { + return nil + } + return g.UpdatedAt +} diff --git a/internal/client/pkg/grantkits/grant_kit_create_params.go b/internal/client/pkg/grantkits/grant_kit_create_params.go new file mode 100644 index 0000000..2e11b09 --- /dev/null +++ b/internal/client/pkg/grantkits/grant_kit_create_params.go @@ -0,0 +1,64 @@ +package grantkits + +type GrantKitCreateParams struct { + Name *string `json:"name,omitempty" required:"true"` + Description *string `json:"description,omitempty" required:"true"` + Workflow *GrantWorkflow `json:"workflow,omitempty"` + Policies []Policy `json:"policies,omitempty"` + Output *Output `json:"output,omitempty" required:"true"` +} + +func (g *GrantKitCreateParams) SetName(name string) { + g.Name = &name +} + +func (g *GrantKitCreateParams) GetName() *string { + if g == nil { + return nil + } + return g.Name +} + +func (g *GrantKitCreateParams) SetDescription(description string) { + g.Description = &description +} + +func (g *GrantKitCreateParams) GetDescription() *string { + if g == nil { + return nil + } + return g.Description +} + +func (g *GrantKitCreateParams) SetWorkflow(workflow GrantWorkflow) { + g.Workflow = &workflow +} + +func (g *GrantKitCreateParams) GetWorkflow() *GrantWorkflow { + if g == nil { + return nil + } + return g.Workflow +} + +func (g *GrantKitCreateParams) SetPolicies(policies []Policy) { + g.Policies = policies +} + +func (g *GrantKitCreateParams) GetPolicies() []Policy { + if g == nil { + return nil + } + return g.Policies +} + +func (g *GrantKitCreateParams) SetOutput(output Output) { + g.Output = &output +} + +func (g *GrantKitCreateParams) GetOutput() *Output { + if g == nil { + return nil + } + return g.Output +} diff --git a/internal/client/pkg/grantkits/grant_kit_update_params.go b/internal/client/pkg/grantkits/grant_kit_update_params.go new file mode 100644 index 0000000..f7f4a32 --- /dev/null +++ b/internal/client/pkg/grantkits/grant_kit_update_params.go @@ -0,0 +1,65 @@ +package grantkits + +type GrantKitUpdateParams struct { + // The name of the connection + Name *string `json:"name,omitempty" required:"true"` + Description *string `json:"description,omitempty" required:"true"` + Workflow *GrantWorkflow `json:"workflow,omitempty"` + Output *Output `json:"output,omitempty" required:"true"` + Policies []Policy `json:"policies,omitempty"` +} + +func (g *GrantKitUpdateParams) SetName(name string) { + g.Name = &name +} + +func (g *GrantKitUpdateParams) GetName() *string { + if g == nil { + return nil + } + return g.Name +} + +func (g *GrantKitUpdateParams) SetDescription(description string) { + g.Description = &description +} + +func (g *GrantKitUpdateParams) GetDescription() *string { + if g == nil { + return nil + } + return g.Description +} + +func (g *GrantKitUpdateParams) SetWorkflow(workflow GrantWorkflow) { + g.Workflow = &workflow +} + +func (g *GrantKitUpdateParams) GetWorkflow() *GrantWorkflow { + if g == nil { + return nil + } + return g.Workflow +} + +func (g *GrantKitUpdateParams) SetOutput(output Output) { + g.Output = &output +} + +func (g *GrantKitUpdateParams) GetOutput() *Output { + if g == nil { + return nil + } + return g.Output +} + +func (g *GrantKitUpdateParams) SetPolicies(policies []Policy) { + g.Policies = policies +} + +func (g *GrantKitUpdateParams) GetPolicies() []Policy { + if g == nil { + return nil + } + return g.Policies +} diff --git a/internal/client/pkg/grantkits/grant_kits_service.go b/internal/client/pkg/grantkits/grant_kits_service.go new file mode 100644 index 0000000..5e8a680 --- /dev/null +++ b/internal/client/pkg/grantkits/grant_kits_service.go @@ -0,0 +1,126 @@ +package grantkits + +import ( + "context" + restClient "github.com/go-provider-sdk/internal/clients/rest" + "github.com/go-provider-sdk/internal/clients/rest/httptransport" + "github.com/go-provider-sdk/internal/configmanager" + "github.com/go-provider-sdk/pkg/clientconfig" + "github.com/go-provider-sdk/pkg/shared" +) + +type GrantKitsService struct { + manager *configmanager.ConfigManager +} + +func NewGrantKitsService(manager *configmanager.ConfigManager) *GrantKitsService { + return &GrantKitsService{ + manager: manager, + } +} + +func (api *GrantKitsService) getConfig() *clientconfig.Config { + return api.manager.GetGrantKits() +} + +func (api *GrantKitsService) SetBaseUrl(baseUrl string) { + config := api.getConfig() + config.SetBaseUrl(baseUrl) +} + +func (api *GrantKitsService) SetAccessToken(accessToken string) { + config := api.getConfig() + config.SetAccessToken(accessToken) +} + +// Returns a list of the latest versions of each grant kit in the organization. +// +// Grant Kits are sorted by creation date, descending. +func (api *GrantKitsService) ListGrantKits(ctx context.Context) (*shared.ClientResponse[[]GrantKit], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[[]GrantKit](config) + + request := httptransport.NewRequest(ctx, "GET", "/grant-kits", config) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[[]GrantKit](err) + } + + return shared.NewClientResponse[[]GrantKit](resp), nil +} + +// Creates a new Grant Kit +func (api *GrantKitsService) CreateGrantKit(ctx context.Context, grantKitCreateParams GrantKitCreateParams) (*shared.ClientResponse[GrantKit], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[GrantKit](config) + + request := httptransport.NewRequest(ctx, "POST", "/grant-kits", config) + + request.Body = grantKitCreateParams + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[GrantKit](err) + } + + return shared.NewClientResponse[GrantKit](resp), nil +} + +// Returns the details of a Grant Kit. +func (api *GrantKitsService) GetGrantKitById(ctx context.Context, grantKitIdOrName string) (*shared.ClientResponse[GrantKit], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[GrantKit](config) + + request := httptransport.NewRequest(ctx, "GET", "/grant-kits/{grant_kit_id_or_name}", config) + + request.SetPathParam("grant_kit_id_or_name", grantKitIdOrName) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[GrantKit](err) + } + + return shared.NewClientResponse[GrantKit](resp), nil +} + +// Updates the specified grant kit. +func (api *GrantKitsService) UpdateGrantKit(ctx context.Context, grantKitIdOrName string, grantKitUpdateParams GrantKitUpdateParams) (*shared.ClientResponse[GrantKit], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[GrantKit](config) + + request := httptransport.NewRequest(ctx, "PUT", "/grant-kits/{grant_kit_id_or_name}", config) + + request.Body = grantKitUpdateParams + + request.SetPathParam("grant_kit_id_or_name", grantKitIdOrName) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[GrantKit](err) + } + + return shared.NewClientResponse[GrantKit](resp), nil +} + +// Deletes the specified grant kit. +func (api *GrantKitsService) DeleteGrantKit(ctx context.Context, grantKitIdOrName string) (*shared.ClientResponse[GrantKit], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[GrantKit](config) + + request := httptransport.NewRequest(ctx, "DELETE", "/grant-kits/{grant_kit_id_or_name}", config) + + request.SetPathParam("grant_kit_id_or_name", grantKitIdOrName) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[GrantKit](err) + } + + return shared.NewClientResponse[GrantKit](resp), nil +} diff --git a/internal/client/pkg/grantkits/grant_workflow.go b/internal/client/pkg/grantkits/grant_workflow.go new file mode 100644 index 0000000..cc13117 --- /dev/null +++ b/internal/client/pkg/grantkits/grant_workflow.go @@ -0,0 +1,16 @@ +package grantkits + +type GrantWorkflow struct { + Steps []Step `json:"steps,omitempty"` +} + +func (g *GrantWorkflow) SetSteps(steps []Step) { + g.Steps = steps +} + +func (g *GrantWorkflow) GetSteps() []Step { + if g == nil { + return nil + } + return g.Steps +} diff --git a/internal/client/pkg/grantkits/output.go b/internal/client/pkg/grantkits/output.go new file mode 100644 index 0000000..2daf7ba --- /dev/null +++ b/internal/client/pkg/grantkits/output.go @@ -0,0 +1,40 @@ +package grantkits + +type Output struct { + Location *string `json:"location,omitempty" required:"true"` + Append *string `json:"append,omitempty"` + Overwrite *string `json:"overwrite,omitempty"` +} + +func (o *Output) SetLocation(location string) { + o.Location = &location +} + +func (o *Output) GetLocation() *string { + if o == nil { + return nil + } + return o.Location +} + +func (o *Output) SetAppend(append string) { + o.Append = &append +} + +func (o *Output) GetAppend() *string { + if o == nil { + return nil + } + return o.Append +} + +func (o *Output) SetOverwrite(overwrite string) { + o.Overwrite = &overwrite +} + +func (o *Output) GetOverwrite() *string { + if o == nil { + return nil + } + return o.Overwrite +} diff --git a/internal/client/pkg/grantkits/policy.go b/internal/client/pkg/grantkits/policy.go new file mode 100644 index 0000000..7bedc5a --- /dev/null +++ b/internal/client/pkg/grantkits/policy.go @@ -0,0 +1,28 @@ +package grantkits + +type Policy struct { + Bundle *string `json:"bundle,omitempty"` + Query *string `json:"query,omitempty"` +} + +func (p *Policy) SetBundle(bundle string) { + p.Bundle = &bundle +} + +func (p *Policy) GetBundle() *string { + if p == nil { + return nil + } + return p.Bundle +} + +func (p *Policy) SetQuery(query string) { + p.Query = &query +} + +func (p *Policy) GetQuery() *string { + if p == nil { + return nil + } + return p.Query +} diff --git a/internal/client/pkg/grantkits/request.go b/internal/client/pkg/grantkits/request.go new file mode 100644 index 0000000..7919a34 --- /dev/null +++ b/internal/client/pkg/grantkits/request.go @@ -0,0 +1,148 @@ +package grantkits + +type Request struct { + Id *string `json:"id,omitempty" required:"true"` + GrantKitId *string `json:"grant_kit_id,omitempty" required:"true"` + GrantKitVersionId *string `json:"grant_kit_version_id,omitempty" required:"true"` + GrantKitName *string `json:"grant_kit_name,omitempty"` + Reason *string `json:"reason,omitempty" required:"true"` + UserId *string `json:"user_id,omitempty" required:"true"` + Status *RequestStatus `json:"status,omitempty" required:"true"` + Reviews []Review `json:"reviews,omitempty"` + GrantId *string `json:"grant_id,omitempty" required:"true"` + CreatedAt *string `json:"created_at,omitempty" required:"true"` + UpdatedAt *string `json:"updated_at,omitempty" required:"true"` + PullRequest *string `json:"pull_request,omitempty" required:"true"` +} + +func (r *Request) SetId(id string) { + r.Id = &id +} + +func (r *Request) GetId() *string { + if r == nil { + return nil + } + return r.Id +} + +func (r *Request) SetGrantKitId(grantKitId string) { + r.GrantKitId = &grantKitId +} + +func (r *Request) GetGrantKitId() *string { + if r == nil { + return nil + } + return r.GrantKitId +} + +func (r *Request) SetGrantKitVersionId(grantKitVersionId string) { + r.GrantKitVersionId = &grantKitVersionId +} + +func (r *Request) GetGrantKitVersionId() *string { + if r == nil { + return nil + } + return r.GrantKitVersionId +} + +func (r *Request) SetGrantKitName(grantKitName string) { + r.GrantKitName = &grantKitName +} + +func (r *Request) GetGrantKitName() *string { + if r == nil { + return nil + } + return r.GrantKitName +} + +func (r *Request) SetReason(reason string) { + r.Reason = &reason +} + +func (r *Request) GetReason() *string { + if r == nil { + return nil + } + return r.Reason +} + +func (r *Request) SetUserId(userId string) { + r.UserId = &userId +} + +func (r *Request) GetUserId() *string { + if r == nil { + return nil + } + return r.UserId +} + +func (r *Request) SetStatus(status RequestStatus) { + r.Status = &status +} + +func (r *Request) GetStatus() *RequestStatus { + if r == nil { + return nil + } + return r.Status +} + +func (r *Request) SetReviews(reviews []Review) { + r.Reviews = reviews +} + +func (r *Request) GetReviews() []Review { + if r == nil { + return nil + } + return r.Reviews +} + +func (r *Request) SetGrantId(grantId string) { + r.GrantId = &grantId +} + +func (r *Request) GetGrantId() *string { + if r == nil { + return nil + } + return r.GrantId +} + +func (r *Request) SetCreatedAt(createdAt string) { + r.CreatedAt = &createdAt +} + +func (r *Request) GetCreatedAt() *string { + if r == nil { + return nil + } + return r.CreatedAt +} + +func (r *Request) SetUpdatedAt(updatedAt string) { + r.UpdatedAt = &updatedAt +} + +func (r *Request) GetUpdatedAt() *string { + if r == nil { + return nil + } + return r.UpdatedAt +} + +func (r *Request) SetPullRequest(pullRequest string) { + r.PullRequest = &pullRequest +} + +func (r *Request) GetPullRequest() *string { + if r == nil { + return nil + } + return r.PullRequest +} diff --git a/internal/client/pkg/grantkits/request_status.go b/internal/client/pkg/grantkits/request_status.go new file mode 100644 index 0000000..2fbe1dc --- /dev/null +++ b/internal/client/pkg/grantkits/request_status.go @@ -0,0 +1,10 @@ +package grantkits + +type RequestStatus string + +const ( + REQUEST_STATUS_PENDING RequestStatus = "Pending" + REQUEST_STATUS_DENIED RequestStatus = "Denied" + REQUEST_STATUS_APPROVED RequestStatus = "Approved" + REQUEST_STATUS_CANCELED RequestStatus = "Canceled" +) diff --git a/internal/client/pkg/grantkits/review.go b/internal/client/pkg/grantkits/review.go new file mode 100644 index 0000000..7138b99 --- /dev/null +++ b/internal/client/pkg/grantkits/review.go @@ -0,0 +1,172 @@ +package grantkits + +type Review struct { + Id *string `json:"id,omitempty" required:"true"` + UserId *string `json:"user_id,omitempty" required:"true"` + UserEmail *string `json:"user_email,omitempty"` + RequestId *string `json:"request_id,omitempty" required:"true"` + Status *ReviewStatus `json:"status,omitempty" required:"true"` + RequestReason *string `json:"request_reason,omitempty" required:"true"` + Reason *string `json:"reason,omitempty" required:"true"` + GrantKitVersionId *string `json:"grant_kit_version_id,omitempty" required:"true"` + GrantKitName *string `json:"grant_kit_name,omitempty" required:"true"` + GrantId *string `json:"grant_id,omitempty" required:"true"` + Grant *Grant `json:"grant,omitempty"` + CreatedAt *string `json:"created_at,omitempty" required:"true"` + UpdatedAt *string `json:"updated_at,omitempty" required:"true"` + PullRequest *string `json:"pull_request,omitempty" required:"true"` +} + +func (r *Review) SetId(id string) { + r.Id = &id +} + +func (r *Review) GetId() *string { + if r == nil { + return nil + } + return r.Id +} + +func (r *Review) SetUserId(userId string) { + r.UserId = &userId +} + +func (r *Review) GetUserId() *string { + if r == nil { + return nil + } + return r.UserId +} + +func (r *Review) SetUserEmail(userEmail string) { + r.UserEmail = &userEmail +} + +func (r *Review) GetUserEmail() *string { + if r == nil { + return nil + } + return r.UserEmail +} + +func (r *Review) SetRequestId(requestId string) { + r.RequestId = &requestId +} + +func (r *Review) GetRequestId() *string { + if r == nil { + return nil + } + return r.RequestId +} + +func (r *Review) SetStatus(status ReviewStatus) { + r.Status = &status +} + +func (r *Review) GetStatus() *ReviewStatus { + if r == nil { + return nil + } + return r.Status +} + +func (r *Review) SetRequestReason(requestReason string) { + r.RequestReason = &requestReason +} + +func (r *Review) GetRequestReason() *string { + if r == nil { + return nil + } + return r.RequestReason +} + +func (r *Review) SetReason(reason string) { + r.Reason = &reason +} + +func (r *Review) GetReason() *string { + if r == nil { + return nil + } + return r.Reason +} + +func (r *Review) SetGrantKitVersionId(grantKitVersionId string) { + r.GrantKitVersionId = &grantKitVersionId +} + +func (r *Review) GetGrantKitVersionId() *string { + if r == nil { + return nil + } + return r.GrantKitVersionId +} + +func (r *Review) SetGrantKitName(grantKitName string) { + r.GrantKitName = &grantKitName +} + +func (r *Review) GetGrantKitName() *string { + if r == nil { + return nil + } + return r.GrantKitName +} + +func (r *Review) SetGrantId(grantId string) { + r.GrantId = &grantId +} + +func (r *Review) GetGrantId() *string { + if r == nil { + return nil + } + return r.GrantId +} + +func (r *Review) SetGrant(grant Grant) { + r.Grant = &grant +} + +func (r *Review) GetGrant() *Grant { + if r == nil { + return nil + } + return r.Grant +} + +func (r *Review) SetCreatedAt(createdAt string) { + r.CreatedAt = &createdAt +} + +func (r *Review) GetCreatedAt() *string { + if r == nil { + return nil + } + return r.CreatedAt +} + +func (r *Review) SetUpdatedAt(updatedAt string) { + r.UpdatedAt = &updatedAt +} + +func (r *Review) GetUpdatedAt() *string { + if r == nil { + return nil + } + return r.UpdatedAt +} + +func (r *Review) SetPullRequest(pullRequest string) { + r.PullRequest = &pullRequest +} + +func (r *Review) GetPullRequest() *string { + if r == nil { + return nil + } + return r.PullRequest +} diff --git a/internal/client/pkg/grantkits/review_status.go b/internal/client/pkg/grantkits/review_status.go new file mode 100644 index 0000000..1fa3319 --- /dev/null +++ b/internal/client/pkg/grantkits/review_status.go @@ -0,0 +1,10 @@ +package grantkits + +type ReviewStatus string + +const ( + REVIEW_STATUS_PENDING ReviewStatus = "Pending" + REVIEW_STATUS_DENIED ReviewStatus = "Denied" + REVIEW_STATUS_APPROVED ReviewStatus = "Approved" + REVIEW_STATUS_CANCELED ReviewStatus = "Canceled" +) diff --git a/internal/client/pkg/grantkits/reviewers.go b/internal/client/pkg/grantkits/reviewers.go new file mode 100644 index 0000000..3a96a67 --- /dev/null +++ b/internal/client/pkg/grantkits/reviewers.go @@ -0,0 +1,28 @@ +package grantkits + +type Reviewers struct { + OneOf []string `json:"one_of,omitempty"` + AllOf []string `json:"all_of,omitempty"` +} + +func (r *Reviewers) SetOneOf(oneOf []string) { + r.OneOf = oneOf +} + +func (r *Reviewers) GetOneOf() []string { + if r == nil { + return nil + } + return r.OneOf +} + +func (r *Reviewers) SetAllOf(allOf []string) { + r.AllOf = allOf +} + +func (r *Reviewers) GetAllOf() []string { + if r == nil { + return nil + } + return r.AllOf +} diff --git a/internal/client/pkg/grantkits/step.go b/internal/client/pkg/grantkits/step.go new file mode 100644 index 0000000..bbf7a3d --- /dev/null +++ b/internal/client/pkg/grantkits/step.go @@ -0,0 +1,28 @@ +package grantkits + +type Step struct { + Reviewers *Reviewers `json:"reviewers,omitempty"` + SkipIf []Policy `json:"skip_if,omitempty"` +} + +func (s *Step) SetReviewers(reviewers Reviewers) { + s.Reviewers = &reviewers +} + +func (s *Step) GetReviewers() *Reviewers { + if s == nil { + return nil + } + return s.Reviewers +} + +func (s *Step) SetSkipIf(skipIf []Policy) { + s.SkipIf = skipIf +} + +func (s *Step) GetSkipIf() []Policy { + if s == nil { + return nil + } + return s.SkipIf +} diff --git a/internal/client/pkg/identities/identities_service.go b/internal/client/pkg/identities/identities_service.go new file mode 100644 index 0000000..171a498 --- /dev/null +++ b/internal/client/pkg/identities/identities_service.go @@ -0,0 +1,126 @@ +package identities + +import ( + "context" + restClient "github.com/go-provider-sdk/internal/clients/rest" + "github.com/go-provider-sdk/internal/clients/rest/httptransport" + "github.com/go-provider-sdk/internal/configmanager" + "github.com/go-provider-sdk/pkg/clientconfig" + "github.com/go-provider-sdk/pkg/shared" +) + +type IdentitiesService struct { + manager *configmanager.ConfigManager +} + +func NewIdentitiesService(manager *configmanager.ConfigManager) *IdentitiesService { + return &IdentitiesService{ + manager: manager, + } +} + +func (api *IdentitiesService) getConfig() *clientconfig.Config { + return api.manager.GetIdentities() +} + +func (api *IdentitiesService) SetBaseUrl(baseUrl string) { + config := api.getConfig() + config.SetBaseUrl(baseUrl) +} + +func (api *IdentitiesService) SetAccessToken(accessToken string) { + config := api.getConfig() + config.SetAccessToken(accessToken) +} + +// Returns all Identities with enriched metadata in the org +func (api *IdentitiesService) ListEnrichedIdentities(ctx context.Context) (*shared.ClientResponse[[]Identity], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[[]Identity](config) + + request := httptransport.NewRequest(ctx, "GET", "/identities", config) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[[]Identity](err) + } + + return shared.NewClientResponse[[]Identity](resp), nil +} + +// Creates a new identity. +// +// An identity represents a human, service, or workload. +func (api *IdentitiesService) CreateIdentity(ctx context.Context, identityParams IdentityParams) (*shared.ClientResponse[Identity], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[Identity](config) + + request := httptransport.NewRequest(ctx, "POST", "/identities", config) + + request.Body = identityParams + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[Identity](err) + } + + return shared.NewClientResponse[Identity](resp), nil +} + +// Returns the details of an identity. +func (api *IdentitiesService) GetIdentity(ctx context.Context, identityId string) (*shared.ClientResponse[Identity], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[Identity](config) + + request := httptransport.NewRequest(ctx, "GET", "/identities/{identity_id}", config) + + request.SetPathParam("identity_id", identityId) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[Identity](err) + } + + return shared.NewClientResponse[Identity](resp), nil +} + +// Updates an identity. +func (api *IdentitiesService) UpdateIdentity(ctx context.Context, identityId string, identityParams IdentityParams) (*shared.ClientResponse[Identity], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[Identity](config) + + request := httptransport.NewRequest(ctx, "PUT", "/identities/{identity_id}", config) + + request.Body = identityParams + + request.SetPathParam("identity_id", identityId) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[Identity](err) + } + + return shared.NewClientResponse[Identity](resp), nil +} + +// Deletes the specified identity. +func (api *IdentitiesService) DeleteIdentity(ctx context.Context, identityId string) (*shared.ClientResponse[any], *shared.ClientError) { + config := *api.getConfig() + + client := restClient.NewRestClient[any](config) + + request := httptransport.NewRequest(ctx, "DELETE", "/identities/{identity_id}", config) + + request.SetPathParam("identity_id", identityId) + + resp, err := client.Call(request) + if err != nil { + return nil, shared.NewClientError[any](err) + } + + return shared.NewClientResponse[any](resp), nil +} diff --git a/internal/client/pkg/identities/identity.go b/internal/client/pkg/identities/identity.go new file mode 100644 index 0000000..0384cc4 --- /dev/null +++ b/internal/client/pkg/identities/identity.go @@ -0,0 +1,77 @@ +package identities + +type Identity struct { + Id *string `json:"id,omitempty"` + CreatedAt *string `json:"created_at,omitempty"` + UpdatedAt *string `json:"updated_at,omitempty"` + AbbeyAccount *string `json:"abbey_account,omitempty" required:"true"` + Source *string `json:"source,omitempty" required:"true"` + // Json encoded string. See documentation for details. + Metadata *string `json:"metadata,omitempty" required:"true"` +} + +func (i *Identity) SetId(id string) { + i.Id = &id +} + +func (i *Identity) GetId() *string { + if i == nil { + return nil + } + return i.Id +} + +func (i *Identity) SetCreatedAt(createdAt string) { + i.CreatedAt = &createdAt +} + +func (i *Identity) GetCreatedAt() *string { + if i == nil { + return nil + } + return i.CreatedAt +} + +func (i *Identity) SetUpdatedAt(updatedAt string) { + i.UpdatedAt = &updatedAt +} + +func (i *Identity) GetUpdatedAt() *string { + if i == nil { + return nil + } + return i.UpdatedAt +} + +func (i *Identity) SetAbbeyAccount(abbeyAccount string) { + i.AbbeyAccount = &abbeyAccount +} + +func (i *Identity) GetAbbeyAccount() *string { + if i == nil { + return nil + } + return i.AbbeyAccount +} + +func (i *Identity) SetSource(source string) { + i.Source = &source +} + +func (i *Identity) GetSource() *string { + if i == nil { + return nil + } + return i.Source +} + +func (i *Identity) SetMetadata(metadata string) { + i.Metadata = &metadata +} + +func (i *Identity) GetMetadata() *string { + if i == nil { + return nil + } + return i.Metadata +} diff --git a/internal/client/pkg/identities/identity_params.go b/internal/client/pkg/identities/identity_params.go new file mode 100644 index 0000000..d904351 --- /dev/null +++ b/internal/client/pkg/identities/identity_params.go @@ -0,0 +1,41 @@ +package identities + +type IdentityParams struct { + AbbeyAccount *string `json:"abbey_account,omitempty" required:"true"` + Source *string `json:"source,omitempty" required:"true"` + // Json encoded string. See documentation for details. + Metadata *string `json:"metadata,omitempty" required:"true"` +} + +func (i *IdentityParams) SetAbbeyAccount(abbeyAccount string) { + i.AbbeyAccount = &abbeyAccount +} + +func (i *IdentityParams) GetAbbeyAccount() *string { + if i == nil { + return nil + } + return i.AbbeyAccount +} + +func (i *IdentityParams) SetSource(source string) { + i.Source = &source +} + +func (i *IdentityParams) GetSource() *string { + if i == nil { + return nil + } + return i.Source +} + +func (i *IdentityParams) SetMetadata(metadata string) { + i.Metadata = &metadata +} + +func (i *IdentityParams) GetMetadata() *string { + if i == nil { + return nil + } + return i.Metadata +} diff --git a/internal/client/pkg/shared/client_error.go b/internal/client/pkg/shared/client_error.go new file mode 100644 index 0000000..1e235ba --- /dev/null +++ b/internal/client/pkg/shared/client_error.go @@ -0,0 +1,31 @@ +package shared + +import ( + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +type ClientError struct { + Err error + Body []byte + Metadata ClientErrorMetadata +} + +type ClientErrorMetadata struct { + Headers map[string]string + StatusCode int +} + +func NewClientError[T any](transportError *httptransport.ErrorResponse[T]) *ClientError { + return &ClientError{ + Err: transportError.GetError(), + Body: transportError.GetBody(), + Metadata: ClientErrorMetadata{ + StatusCode: transportError.GetStatusCode(), + Headers: transportError.GetHeaders(), + }, + } +} + +func (e *ClientError) Error() string { + return e.Err.Error() +} diff --git a/internal/client/pkg/shared/client_response.go b/internal/client/pkg/shared/client_response.go new file mode 100644 index 0000000..5ff7ebb --- /dev/null +++ b/internal/client/pkg/shared/client_response.go @@ -0,0 +1,25 @@ +package shared + +import ( + "github.com/go-provider-sdk/internal/clients/rest/httptransport" +) + +type ClientResponse[T any] struct { + Data T + Metadata ClientResponseMetadata +} + +type ClientResponseMetadata struct { + Headers map[string]string + StatusCode int +} + +func NewClientResponse[T any](resp *httptransport.Response[T]) *ClientResponse[T] { + return &ClientResponse[T]{ + Data: resp.Data, + Metadata: ClientResponseMetadata{ + StatusCode: resp.StatusCode, + Headers: resp.Headers, + }, + } +} diff --git a/internal/planmodifiers/boolplanmodifier/suppress_diff.go b/internal/planmodifiers/boolplanmodifier/suppress_diff.go deleted file mode 100755 index c75b8e2..0000000 --- a/internal/planmodifiers/boolplanmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package boolplanmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.Bool { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyBool implements the plan modification logic. -func (m suppressDiff) PlanModifyBool(ctx context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/float64planmodifier/suppress_diff.go b/internal/planmodifiers/float64planmodifier/suppress_diff.go deleted file mode 100755 index 322f727..0000000 --- a/internal/planmodifiers/float64planmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package float64planmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.Float64 { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyFloat64 implements the plan modification logic. -func (m suppressDiff) PlanModifyFloat64(ctx context.Context, req planmodifier.Float64Request, resp *planmodifier.Float64Response) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/int64planmodifier/suppress_diff.go b/internal/planmodifiers/int64planmodifier/suppress_diff.go deleted file mode 100755 index ed3d5e4..0000000 --- a/internal/planmodifiers/int64planmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package int64planmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.Int64 { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyInt64 implements the plan modification logic. -func (m suppressDiff) PlanModifyInt64(ctx context.Context, req planmodifier.Int64Request, resp *planmodifier.Int64Response) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/listplanmodifier/suppress_diff.go b/internal/planmodifiers/listplanmodifier/suppress_diff.go deleted file mode 100755 index 53d0e92..0000000 --- a/internal/planmodifiers/listplanmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package listplanmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.List { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyList implements the plan modification logic. -func (m suppressDiff) PlanModifyList(ctx context.Context, req planmodifier.ListRequest, resp *planmodifier.ListResponse) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/mapplanmodifier/suppress_diff.go b/internal/planmodifiers/mapplanmodifier/suppress_diff.go deleted file mode 100755 index 0e7e408..0000000 --- a/internal/planmodifiers/mapplanmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package mapplanmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.Map { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyMap implements the plan modification logic. -func (m suppressDiff) PlanModifyMap(ctx context.Context, req planmodifier.MapRequest, resp *planmodifier.MapResponse) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/numberplanmodifier/suppress_diff.go b/internal/planmodifiers/numberplanmodifier/suppress_diff.go deleted file mode 100755 index c9ec635..0000000 --- a/internal/planmodifiers/numberplanmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package numberplanmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.Number { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyNumber implements the plan modification logic. -func (m suppressDiff) PlanModifyNumber(ctx context.Context, req planmodifier.NumberRequest, resp *planmodifier.NumberResponse) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/objectplanmodifier/suppress_diff.go b/internal/planmodifiers/objectplanmodifier/suppress_diff.go deleted file mode 100755 index 16ce212..0000000 --- a/internal/planmodifiers/objectplanmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package objectplanmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.Object { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyObject implements the plan modification logic. -func (m suppressDiff) PlanModifyObject(ctx context.Context, req planmodifier.ObjectRequest, resp *planmodifier.ObjectResponse) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/setplanmodifier/suppress_diff.go b/internal/planmodifiers/setplanmodifier/suppress_diff.go deleted file mode 100755 index ff78f57..0000000 --- a/internal/planmodifiers/setplanmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package setplanmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.Set { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifySet implements the plan modification logic. -func (m suppressDiff) PlanModifySet(ctx context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/stringplanmodifier/suppress_diff.go b/internal/planmodifiers/stringplanmodifier/suppress_diff.go deleted file mode 100755 index f433a16..0000000 --- a/internal/planmodifiers/stringplanmodifier/suppress_diff.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package stringplanmodifier - -import ( - "abbey/v2/internal/planmodifiers/utils" - "context" - - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// SuppressDiff returns a plan modifier that propagates a state value into the planned value, when it is Known, and the Plan Value is Unknown -func SuppressDiff() planmodifier.String { - return suppressDiff{} -} - -// suppressDiff implements the plan modifier. -type suppressDiff struct{} - -// Description returns a human-readable description of the plan modifier. -func (m suppressDiff) Description(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// MarkdownDescription returns a markdown description of the plan modifier. -func (m suppressDiff) MarkdownDescription(_ context.Context) string { - return "Once set, the value of this attribute in state will not change." -} - -// PlanModifyString implements the plan modification logic. -func (m suppressDiff) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { - // Do nothing if there is a known planned value. - if !req.PlanValue.IsUnknown() { - return - } - - // Do nothing if there is an unknown configuration value - if req.ConfigValue.IsUnknown() { - return - } - - if utils.IsAllStateUnknown(ctx, req.State) { - return - } - - resp.PlanValue = req.StateValue -} diff --git a/internal/planmodifiers/utils/state_check.go b/internal/planmodifiers/utils/state_check.go deleted file mode 100755 index 66d9150..0000000 --- a/internal/planmodifiers/utils/state_check.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "context" - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" -) - -func IsAllStateUnknown(ctx context.Context, state tfsdk.State) bool { - attrs := state.Schema.GetAttributes() - anyFound := false - for k, _ := range attrs { - attrValue := new(attr.Value) - state.GetAttribute(ctx, path.Root(k), attrValue) - if attrValue != nil && !(*attrValue).IsUnknown() && !(*attrValue).IsNull() { - anyFound = true - break - } - } - - return !anyFound -} diff --git a/internal/provider/demo/acceptance/resource_e2e_test.go b/internal/provider/demo/acceptance/resource_e2e_test.go new file mode 100644 index 0000000..039fcc0 --- /dev/null +++ b/internal/provider/demo/acceptance/resource_e2e_test.go @@ -0,0 +1,116 @@ +//go:build acceptance +// +build acceptance + +package acceptance + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "path" + "testing" + + "abbey/v2/internal/provider" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func getDemoProviderConfig(serverUrl string) string { + return fmt.Sprintf(` + provider "abbey" { + server_url = "server_url" + bearer_auth = "bearer_auth" +} + + `, serverUrl) +} + +func setupDemoMockServer() *httptest.Server { + db := make(map[string]*demo.Demo) + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if req.Method == http.MethodGet { + Id := path.Base(req.URL.Path) + demo := db[Id] + data, _ := json.Marshal(demo) + + rw.Write(data) + return + } + if req.Method == http.MethodPost { + id := "id" + + demo := demo.Demo{} + + bodyBytes, _ := io.ReadAll(req.Body) + json.Unmarshal(bodyBytes, &demo) + + demo.SetId(id) + data, _ := json.Marshal(demo) + + db[id] = &demo + + rw.Write(data) + return + } + if req.Method == http.MethodPatch || req.Method == http.MethodPut { + demoId := path.Base(req.URL.Path) + + if db[demoId] == nil { + rw.Write([]byte("Error")) + return + } + + demo := demo.Demo{} + + bodyBytes, _ := io.ReadAll(req.Body) + json.Unmarshal(bodyBytes, &demo) + + demo.SetId(demoId) + data, _ := json.Marshal(demo) + + db[demoId] = &demo + + rw.Write(data) + return + } + })) + + return server +} + +func TestAccabbeyDemoResource(t *testing.T) { + testAccProtoV6ProviderFactories := map[string]func() (tfprotov6.ProviderServer, error){ + "abbey": providerserver.NewProtocol6WithError(provider.New("test")()), + } + + server := setupDemoMockServer() + defer server.Close() + providerConfig := getDemoProviderConfig(server.URL) + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read + { + Config: providerConfig + + ` +resource "abbey_demo" "example" { + email = "email" + + permission = "permission" + +} + +`, + Check: resource.ComposeAggregateTestCheckFunc( + // Extend this based on the model attributes + resource.TestCheckResourceAttr("abbey_demo.example", "email", "email"), + resource.TestCheckResourceAttr("abbey_demo.example", "permission", "permission"), + ), + }, + }, + }) +} diff --git a/internal/provider/demo/resource.go b/internal/provider/demo/resource.go new file mode 100644 index 0000000..4c0de59 --- /dev/null +++ b/internal/provider/demo/resource.go @@ -0,0 +1,234 @@ +package demo + +import ( + "abbey/v2/internal/utils" + "context" + "fmt" + "github.com/go-provider-sdk/pkg/client" + "github.com/go-provider-sdk/pkg/demo" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// ensure we implement the needed interfaces +var _ resource.Resource = &DemoResource{} +var _ resource.ResourceWithImportState = &DemoResource{} + +// constructor +func NewDemoResource() resource.Resource { + return &DemoResource{} +} + +// client wrapper +type DemoResource struct { + client *client.Client +} + +type DemoResourceModel struct { + Email types.String `tfsdk:"email"` + Id types.Int64 `tfsdk:"id"` + UserId types.String `tfsdk:"user_id"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` + Permission types.String `tfsdk:"permission"` +} + +func (r *DemoResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_demo" +} + +func (r *DemoResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + + Attributes: map[string]schema.Attribute{ + "email": schema.StringAttribute{ + Description: "The email of the user", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + + "id": schema.Int64Attribute{ + Description: "id", + Computed: true, + Optional: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + + "user_id": schema.StringAttribute{ + Description: "user_id", + Computed: true, + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + + "created_at": schema.StringAttribute{ + Description: "created_at", + Computed: true, + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + + "updated_at": schema.StringAttribute{ + Description: "updated_at", + Computed: true, + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + + "permission": schema.StringAttribute{ + Description: "permission", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + }, + } +} + +func (r *DemoResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + apiClient, ok := req.ProviderData.(*client.Client) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + r.client = apiClient +} + +func (r *DemoResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var dataModel DemoResourceModel + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.State.Get) + + if resp.Diagnostics.HasError() { + return + } + + params := demo.GetDemoRequestParams{} + params.SetEmail(dataModel.Email.ValueString()) + + if resp.Diagnostics.HasError() { + return + } + + clientResponse, err := r.client.Demo.GetDemo(ctx, params) + if err != nil { + resp.Diagnostics.AddError( + "Unexpected error calling Demo.GetDemo", + err.Error(), + ) + + return + } + + demo := clientResponse.Data + + dataModel.Id = utils.NullableInt64(demo.GetId()) + + dataModel.UserId = utils.NullableString(demo.GetUserId()) + + dataModel.CreatedAt = utils.NullableString(demo.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(demo.GetUpdatedAt()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *DemoResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var dataModel DemoResourceModel + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.Plan.Get) + + if resp.Diagnostics.HasError() { + return + } + + requestBody := demo.DemoParams{ + Permission: utils.Pointer(demo.Permission(dataModel.Permission.ValueString())), + Email: dataModel.Email.ValueStringPointer(), + } + + clientResponse, err := r.client.Demo.CreateDemo(ctx, requestBody) + + if err != nil { + resp.Diagnostics.AddError( + "Error Creating Demo", + err.Error(), + ) + + return + } + + demo := clientResponse.Data + dataModel.Id = utils.NullableInt64(demo.GetId()) + + dataModel.UserId = utils.NullableString(demo.GetUserId()) + + dataModel.CreatedAt = utils.NullableString(demo.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(demo.GetUpdatedAt()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *DemoResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var dataModel = &DemoResourceModel{} + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.State.Get) + + if resp.Diagnostics.HasError() { + return + } + + requestBody := demo.DemoParams{ + Permission: utils.Pointer(demo.Permission(dataModel.Permission.ValueString())), + Email: dataModel.Email.ValueStringPointer(), + } + + _, err := r.client.Demo.DeleteDemo(ctx, requestBody) + + if err != nil { + resp.Diagnostics.AddError( + "Error Deleting Demo", + err.Error(), + ) + } +} + +func (r *DemoResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { +} + +func (r *DemoResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + // Retrieve import ID and save to id attribute + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} diff --git a/internal/provider/demo/resource_test.go b/internal/provider/demo/resource_test.go new file mode 100644 index 0000000..64a8255 --- /dev/null +++ b/internal/provider/demo/resource_test.go @@ -0,0 +1,39 @@ +//go:build unit +// +build unit + +package demo + +import ( + "context" + "github.com/go-provider-sdk/pkg/client" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestConfigureResource(t *testing.T) { + // mock client + mockClient := &client.Client{} + + // create DemoResource instance + resourceInstance := NewDemoResource() + + // Type-assert to the concrete type + r, ok := resourceInstance.(*DemoResource) + if !ok { + t.Fatalf("Failed to type assert resourceInstance to *DemoResource") + } + + // create mock ConfigureRequest + req := resource.ConfigureRequest{ + ProviderData: mockClient, + } + + var resp resource.ConfigureResponse + + r.Configure(context.Background(), req, &resp) + + // assertions + assert.False(t, resp.Diagnostics.HasError()) + assert.Equal(t, mockClient, r.client, "Expected client to be set correctly in DemoResource") +} diff --git a/internal/provider/demo_resource.go b/internal/provider/demo_resource.go deleted file mode 100755 index 434e172..0000000 --- a/internal/provider/demo_resource.go +++ /dev/null @@ -1,229 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk" - "context" - "fmt" - - "abbey/v2/internal/validators" - "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" -) - -// Ensure provider defined types fully satisfy framework interfaces. -var _ resource.Resource = &DemoResource{} -var _ resource.ResourceWithImportState = &DemoResource{} - -func NewDemoResource() resource.Resource { - return &DemoResource{} -} - -// DemoResource defines the resource implementation. -type DemoResource struct { - client *sdk.SDK -} - -// DemoResourceModel describes the resource data model. -type DemoResourceModel struct { - CreatedAt types.String `tfsdk:"created_at"` - Email types.String `tfsdk:"email"` - ID types.Int64 `tfsdk:"id"` - Permission types.String `tfsdk:"permission"` - UpdatedAt types.String `tfsdk:"updated_at"` - UserID types.String `tfsdk:"user_id"` -} - -func (r *DemoResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_demo" -} - -func (r *DemoResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - resp.Schema = schema.Schema{ - MarkdownDescription: "Demo Resource", - - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "email": schema.StringAttribute{ - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), - }, - Required: true, - }, - "id": schema.Int64Attribute{ - Computed: true, - }, - "permission": schema.StringAttribute{ - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), - }, - Required: true, - Validators: []validator.String{ - stringvalidator.OneOf( - "read_write", - ), - }, - Description: `must be one of [read_write]`, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - } -} - -func (r *DemoResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - // Prevent panic if the provider has not been configured. - if req.ProviderData == nil { - return - } - - client, ok := req.ProviderData.(*sdk.SDK) - - if !ok { - resp.Diagnostics.AddError( - "Unexpected Resource Configure Type", - fmt.Sprintf("Expected *sdk.SDK, got: %T. Please report this issue to the provider developers.", req.ProviderData), - ) - - return - } - - r.client = client -} - -func (r *DemoResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data *DemoResourceModel - var item types.Object - - resp.Diagnostics.Append(req.Plan.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - request := *data.ToCreateSDKType() - res, err := r.client.Demo.CreateDemo(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 201 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.Demo == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromCreateResponse(res.Demo) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *DemoResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data *DemoResourceModel - var item types.Object - - resp.Diagnostics.Append(req.State.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - // Not Implemented; we rely entirely on CREATE API request response - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *DemoResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data *DemoResourceModel - merge(ctx, req, resp, &data) - if resp.Diagnostics.HasError() { - return - } - - // Not Implemented; all attributes marked as RequiresReplace - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *DemoResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var data *DemoResourceModel - var item types.Object - - resp.Diagnostics.Append(req.State.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - request := *data.ToDeleteSDKType() - res, err := r.client.Demo.DeleteDemo(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - -} - -func (r *DemoResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.AddError("Not Implemented", "No available import state operation is available for resource demo.") -} diff --git a/internal/provider/demo_resource_sdk.go b/internal/provider/demo_resource_sdk.go deleted file mode 100755 index 020205b..0000000 --- a/internal/provider/demo_resource_sdk.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "github.com/hashicorp/terraform-plugin-framework/types" - "time" -) - -func (r *DemoResourceModel) ToCreateSDKType() *shared.DemoParams { - email := r.Email.ValueString() - permission := shared.DemoParamsPermission(r.Permission.ValueString()) - out := shared.DemoParams{ - Email: email, - Permission: permission, - } - return &out -} - -func (r *DemoResourceModel) ToDeleteSDKType() *shared.DemoParams { - out := r.ToCreateSDKType() - return out -} - -func (r *DemoResourceModel) RefreshFromCreateResponse(resp *shared.Demo) { - if resp.CreatedAt != nil { - r.CreatedAt = types.StringValue(resp.CreatedAt.Format(time.RFC3339)) - } else { - r.CreatedAt = types.StringNull() - } - if resp.ID != nil { - r.ID = types.Int64Value(*resp.ID) - } else { - r.ID = types.Int64Null() - } - if resp.UpdatedAt != nil { - r.UpdatedAt = types.StringValue(resp.UpdatedAt.Format(time.RFC3339)) - } else { - r.UpdatedAt = types.StringNull() - } - if resp.UserID != nil { - r.UserID = types.StringValue(*resp.UserID) - } else { - r.UserID = types.StringNull() - } -} diff --git a/internal/provider/grantkit/acceptance/resource_e2e_test.go b/internal/provider/grantkit/acceptance/resource_e2e_test.go new file mode 100644 index 0000000..4779522 --- /dev/null +++ b/internal/provider/grantkit/acceptance/resource_e2e_test.go @@ -0,0 +1,174 @@ +//go:build acceptance +// +build acceptance + +package acceptance + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "path" + "testing" + + "abbey/v2/internal/provider" + "abbey/v2/internal/shared/models/grant" + "abbey/v2/internal/shared/models/grant_workflow" + "abbey/v2/internal/shared/models/output" + "abbey/v2/internal/shared/models/policy" + "abbey/v2/internal/shared/models/request" + "abbey/v2/internal/shared/models/review" + "abbey/v2/internal/shared/models/reviewers" + "abbey/v2/internal/shared/models/step" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func getGrantKitProviderConfig(serverUrl string) string { + return fmt.Sprintf(` + provider "abbey" { + server_url = "server_url" + bearer_auth = "bearer_auth" +} + + `, serverUrl) +} + +func setupGrantKitMockServer() *httptest.Server { + db := make(map[string]*grantkit.GrantKit) + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if req.Method == http.MethodGet { + Id := path.Base(req.URL.Path) + grant_kit := db[Id] + data, _ := json.Marshal(grant_kit) + + rw.Write(data) + return + } + if req.Method == http.MethodPost { + id := "id" + + grant_kit := grantkit.GrantKit{} + + bodyBytes, _ := io.ReadAll(req.Body) + json.Unmarshal(bodyBytes, &grant_kit) + + grant_kit.SetId(id) + data, _ := json.Marshal(grant_kit) + + db[id] = &grant_kit + + rw.Write(data) + return + } + if req.Method == http.MethodPatch || req.Method == http.MethodPut { + grant_kitId := path.Base(req.URL.Path) + + if db[grant_kitId] == nil { + rw.Write([]byte("Error")) + return + } + + grant_kit := grantkit.GrantKit{} + + bodyBytes, _ := io.ReadAll(req.Body) + json.Unmarshal(bodyBytes, &grant_kit) + + grant_kit.SetId(grant_kitId) + data, _ := json.Marshal(grant_kit) + + db[grant_kitId] = &grant_kit + + rw.Write(data) + return + } + })) + + return server +} + +func TestAccabbeyGrantKitResource(t *testing.T) { + testAccProtoV6ProviderFactories := map[string]func() (tfprotov6.ProviderServer, error){ + "abbey": providerserver.NewProtocol6WithError(provider.New("test")()), + } + + server := setupGrantKitMockServer() + defer server.Close() + providerConfig := getGrantKitProviderConfig(server.URL) + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read + { + Config: providerConfig + + ` +resource "abbey_grant_kit" "example" { + name = "name" + + description = "description" + + workflow = { + steps = [ + { + reviewers = { + one_of = [ + "one_of" + ] + all_of = [ + "all_of" + ] +} + + skip_if = [ + { + bundle = "bundle" + query = "query" +} + + ] +} + + ] +} + + + policies = [ + { + bundle = "bundle" + query = "query" +} + + ] + + output = { + location = "location" + append = "append" + overwrite = "overwrite" +} + + +} + +`, + Check: resource.ComposeAggregateTestCheckFunc( + // Extend this based on the model attributes + resource.TestCheckResourceAttr("abbey_grant_kit.example", "grant_kit_id_or_name", "grant_kit_id_or_name"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "name", "name"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "description", "description"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "workflow.steps.0.reviewers.one_of.0", "one_of"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "workflow.steps.0.reviewers.all_of.0", "all_of"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "workflow.steps.0.skip_if.0.bundle", "bundle"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "workflow.steps.0.skip_if.0.query", "query"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "policies.0.bundle", "bundle"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "policies.0.query", "query"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "output.location", "location"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "output.append", "append"), + resource.TestCheckResourceAttr("abbey_grant_kit.example", "output.overwrite", "overwrite"), + ), + }, + }, + }) +} diff --git a/internal/provider/grantkit/resource.go b/internal/provider/grantkit/resource.go new file mode 100644 index 0000000..9003a6f --- /dev/null +++ b/internal/provider/grantkit/resource.go @@ -0,0 +1,1125 @@ +package grantkit + +import ( + "abbey/v2/internal/shared/models/grant" + "abbey/v2/internal/shared/models/grant_workflow" + "abbey/v2/internal/shared/models/output" + "abbey/v2/internal/shared/models/policy" + "abbey/v2/internal/shared/models/request" + "abbey/v2/internal/shared/models/review" + "abbey/v2/internal/shared/models/reviewers" + "abbey/v2/internal/shared/models/step" + "abbey/v2/internal/utils" + "context" + "fmt" + "github.com/go-provider-sdk/pkg/client" + "github.com/go-provider-sdk/pkg/grantkits" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// ensure we implement the needed interfaces +var _ resource.Resource = &GrantKitResource{} +var _ resource.ResourceWithImportState = &GrantKitResource{} + +// constructor +func NewGrantKitResource() resource.Resource { + return &GrantKitResource{} +} + +// client wrapper +type GrantKitResource struct { + client *client.Client +} + +type GrantKitResourceModel struct { + Id types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + CurrentVersionId types.String `tfsdk:"current_version_id"` + Description types.String `tfsdk:"description"` + MaxGrantDurationInSec types.Float64 `tfsdk:"max_grant_duration_in_sec"` + Workflow *grant_workflow.GrantWorkflow `tfsdk:"workflow"` + Policies []policy.Policy `tfsdk:"policies"` + Output *output.Output `tfsdk:"output"` + Grants []grant.Grant `tfsdk:"grants"` + ResourceType types.String `tfsdk:"resource_type"` + Requests []request.Request `tfsdk:"requests"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` +} + +func (r *GrantKitResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_grant_kit" +} + +func (r *GrantKitResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "id", + Computed: true, + Optional: true, + }, + + "name": schema.StringAttribute{ + Description: "name", + Required: true, + }, + + "current_version_id": schema.StringAttribute{ + Description: "current_version_id", + Computed: true, + Optional: true, + }, + + "description": schema.StringAttribute{ + Description: "description", + Required: true, + }, + + "max_grant_duration_in_sec": schema.Float64Attribute{ + Description: "max_grant_duration_in_sec", + Computed: true, + Optional: true, + }, + + "workflow": schema.SingleNestedAttribute{ + Description: "workflow", + Optional: true, + + Attributes: map[string]schema.Attribute{ + "steps": schema.ListNestedAttribute{ + Description: "steps", + Optional: true, + + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "reviewers": schema.SingleNestedAttribute{ + Description: "reviewers", + Optional: true, + + Attributes: map[string]schema.Attribute{ + "one_of": schema.ListAttribute{ + Description: "one_of", + Optional: true, + + ElementType: types.StringType, + }, + + "all_of": schema.ListAttribute{ + Description: "all_of", + Optional: true, + + ElementType: types.StringType, + }, + }, + }, + + "skip_if": schema.ListNestedAttribute{ + Description: "skip_if", + Optional: true, + + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "bundle": schema.StringAttribute{ + Description: "bundle", + Optional: true, + }, + + "query": schema.StringAttribute{ + Description: "query", + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + + "policies": schema.ListNestedAttribute{ + Description: "policies", + Optional: true, + + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "bundle": schema.StringAttribute{ + Description: "bundle", + Optional: true, + }, + + "query": schema.StringAttribute{ + Description: "query", + Optional: true, + }, + }, + }, + }, + + "output": schema.SingleNestedAttribute{ + Description: "output", + Required: true, + + Attributes: map[string]schema.Attribute{ + "location": schema.StringAttribute{ + Description: "location", + Required: true, + }, + + "append": schema.StringAttribute{ + Description: "append", + Optional: true, + }, + + "overwrite": schema.StringAttribute{ + Description: "overwrite", + Optional: true, + }, + }, + }, + + "grants": schema.ListNestedAttribute{ + Description: "grants", + Computed: true, + Optional: true, + + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "id", + Required: true, + }, + + "grant_kit_id": schema.StringAttribute{ + Description: "grant_kit_id", + Required: true, + }, + + "grant_kit_version_id": schema.StringAttribute{ + Description: "grant_kit_version_id", + Required: true, + }, + + "user_id": schema.StringAttribute{ + Description: "user_id", + Required: true, + }, + + "request_id": schema.StringAttribute{ + Description: "request_id", + Required: true, + }, + + "organization_id": schema.StringAttribute{ + Description: "organization_id", + Required: true, + }, + + "deleted": schema.BoolAttribute{ + Description: "deleted", + Required: true, + }, + + "created_at": schema.StringAttribute{ + Description: "created_at", + Required: true, + }, + + "updated_at": schema.StringAttribute{ + Description: "updated_at", + Required: true, + }, + }, + }, + }, + + "resource_type": schema.StringAttribute{ + Description: "resource_type", + Computed: true, + Optional: true, + }, + + "requests": schema.ListNestedAttribute{ + Description: "requests", + Computed: true, + Optional: true, + + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "id", + Required: true, + }, + + "grant_kit_id": schema.StringAttribute{ + Description: "grant_kit_id", + Required: true, + }, + + "grant_kit_version_id": schema.StringAttribute{ + Description: "grant_kit_version_id", + Required: true, + }, + + "grant_kit_name": schema.StringAttribute{ + Description: "grant_kit_name", + Optional: true, + }, + + "reason": schema.StringAttribute{ + Description: "reason", + Required: true, + }, + + "user_id": schema.StringAttribute{ + Description: "user_id", + Required: true, + }, + + "status": schema.StringAttribute{ + Description: "status", + Required: true, + }, + + "reviews": schema.ListNestedAttribute{ + Description: "reviews", + Optional: true, + + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "id", + Required: true, + }, + + "user_id": schema.StringAttribute{ + Description: "user_id", + Required: true, + }, + + "user_email": schema.StringAttribute{ + Description: "user_email", + Optional: true, + }, + + "request_id": schema.StringAttribute{ + Description: "request_id", + Required: true, + }, + + "status": schema.StringAttribute{ + Description: "status", + Required: true, + }, + + "request_reason": schema.StringAttribute{ + Description: "request_reason", + Required: true, + }, + + "reason": schema.StringAttribute{ + Description: "reason", + Required: true, + }, + + "grant_kit_version_id": schema.StringAttribute{ + Description: "grant_kit_version_id", + Required: true, + }, + + "grant_kit_name": schema.StringAttribute{ + Description: "grant_kit_name", + Required: true, + }, + + "grant_id": schema.StringAttribute{ + Description: "grant_id", + Required: true, + }, + + "grant": schema.SingleNestedAttribute{ + Description: "grant", + Optional: true, + + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "id", + Required: true, + }, + + "grant_kit_id": schema.StringAttribute{ + Description: "grant_kit_id", + Required: true, + }, + + "grant_kit_version_id": schema.StringAttribute{ + Description: "grant_kit_version_id", + Required: true, + }, + + "user_id": schema.StringAttribute{ + Description: "user_id", + Required: true, + }, + + "request_id": schema.StringAttribute{ + Description: "request_id", + Required: true, + }, + + "organization_id": schema.StringAttribute{ + Description: "organization_id", + Required: true, + }, + + "deleted": schema.BoolAttribute{ + Description: "deleted", + Required: true, + }, + + "created_at": schema.StringAttribute{ + Description: "created_at", + Required: true, + }, + + "updated_at": schema.StringAttribute{ + Description: "updated_at", + Required: true, + }, + }, + }, + + "created_at": schema.StringAttribute{ + Description: "created_at", + Required: true, + }, + + "updated_at": schema.StringAttribute{ + Description: "updated_at", + Required: true, + }, + + "pull_request": schema.StringAttribute{ + Description: "pull_request", + Required: true, + }, + }, + }, + }, + + "grant_id": schema.StringAttribute{ + Description: "grant_id", + Required: true, + }, + + "created_at": schema.StringAttribute{ + Description: "created_at", + Required: true, + }, + + "updated_at": schema.StringAttribute{ + Description: "updated_at", + Required: true, + }, + + "pull_request": schema.StringAttribute{ + Description: "pull_request", + Required: true, + }, + }, + }, + }, + + "created_at": schema.StringAttribute{ + Description: "created_at", + Computed: true, + Optional: true, + }, + + "updated_at": schema.StringAttribute{ + Description: "updated_at", + Computed: true, + Optional: true, + }, + }, + } +} + +func (r *GrantKitResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + apiClient, ok := req.ProviderData.(*client.Client) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + r.client = apiClient +} + +func (r *GrantKitResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var dataModel GrantKitResourceModel + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.State.Get) + + if resp.Diagnostics.HasError() { + return + } + + GrantKitIdOrName := dataModel.Id.ValueString() + + clientResponse, err := r.client.GrantKits.GetGrantKitById(ctx, GrantKitIdOrName) + if err != nil { + resp.Diagnostics.AddError( + "Unexpected error calling GrantKits.GetGrantKitById", + err.Error(), + ) + + return + } + + grantKit := clientResponse.Data + + dataModel.Id = utils.NullableString(grantKit.GetId()) + + dataModel.Name = utils.NullableString(grantKit.GetName()) + + dataModel.CurrentVersionId = utils.NullableString(grantKit.GetCurrentVersionId()) + + dataModel.Description = utils.NullableString(grantKit.GetDescription()) + + dataModel.MaxGrantDurationInSec = utils.NullableFloat64(grantKit.GetMaxGrantDurationInSec()) + + if grantKit.Workflow != nil { + dataModel.Workflow = utils.NullableObject(grantKit.Workflow, grant_workflow.GrantWorkflow{ + Steps: utils.MapList(grantKit.GetWorkflow().Steps, func(from grantkits.Step) step.Step { + return step.Step{ + Reviewers: utils.NullableObject(from.Reviewers, reviewers.Reviewers{ + OneOf: utils.ToList(ctx, from.Reviewers.OneOf, types.StringType, &resp.Diagnostics), + + AllOf: utils.ToList(ctx, from.Reviewers.AllOf, types.StringType, &resp.Diagnostics), + }), + + SkipIf: utils.MapList(from.SkipIf, func(from grantkits.Policy) policy.Policy { + return policy.Policy{ + Bundle: utils.NullableString(from.GetBundle()), + + Query: utils.NullableString(from.GetQuery()), + } + }), + } + }), + }) + } + + for index, item := range grantKit.Policies { + dataModel.Policies[index] = policy.Policy{ + Bundle: utils.NullableString(item.GetBundle()), + + Query: utils.NullableString(item.GetQuery()), + } + } + + if grantKit.Output != nil { + dataModel.Output = utils.NullableObject(grantKit.Output, output.Output{ + Location: utils.NullableString(grantKit.GetOutput().GetLocation()), + + Append: utils.NullableString(grantKit.GetOutput().GetAppend()), + + Overwrite: utils.NullableString(grantKit.GetOutput().GetOverwrite()), + }) + } + + for index, item := range grantKit.Grants { + dataModel.Grants[index] = grant.Grant{ + Id: utils.NullableString(item.GetId()), + + GrantKitId: utils.NullableString(item.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(item.GetGrantKitVersionId()), + + UserId: utils.NullableString(item.GetUserId()), + + RequestId: utils.NullableString(item.GetRequestId()), + + OrganizationId: utils.NullableString(item.GetOrganizationId()), + + Deleted: utils.NullableBool(item.GetDeleted()), + + CreatedAt: utils.NullableString(item.GetCreatedAt()), + + UpdatedAt: utils.NullableString(item.GetUpdatedAt()), + } + } + + dataModel.ResourceType = utils.NullableString(grantKit.GetResourceType()) + + for index, item := range grantKit.Requests { + dataModel.Requests[index] = request.Request{ + Id: utils.NullableString(item.GetId()), + + GrantKitId: utils.NullableString(item.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(item.GetGrantKitVersionId()), + + GrantKitName: utils.NullableString(item.GetGrantKitName()), + + Reason: utils.NullableString(item.GetReason()), + + UserId: utils.NullableString(item.GetUserId()), + + Status: types.StringValue(string(*item.GetStatus())), + + Reviews: utils.MapList(item.Reviews, func(from grantkits.Review) review.Review { + return review.Review{ + Id: utils.NullableString(from.GetId()), + + UserId: utils.NullableString(from.GetUserId()), + + UserEmail: utils.NullableString(from.GetUserEmail()), + + RequestId: utils.NullableString(from.GetRequestId()), + + Status: types.StringValue(string(*from.GetStatus())), + + RequestReason: utils.NullableString(from.GetRequestReason()), + + Reason: utils.NullableString(from.GetReason()), + + GrantKitVersionId: utils.NullableString(from.GetGrantKitVersionId()), + + GrantKitName: utils.NullableString(from.GetGrantKitName()), + + GrantId: utils.NullableString(from.GetGrantId()), + + Grant: utils.NullableObject(from.Grant, grant.Grant{ + Id: utils.NullableString(from.Grant.GetId()), + + GrantKitId: utils.NullableString(from.Grant.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(from.Grant.GetGrantKitVersionId()), + + UserId: utils.NullableString(from.Grant.GetUserId()), + + RequestId: utils.NullableString(from.Grant.GetRequestId()), + + OrganizationId: utils.NullableString(from.Grant.GetOrganizationId()), + + Deleted: utils.NullableBool(from.Grant.GetDeleted()), + + CreatedAt: utils.NullableString(from.Grant.GetCreatedAt()), + + UpdatedAt: utils.NullableString(from.Grant.GetUpdatedAt()), + }), + + CreatedAt: utils.NullableString(from.GetCreatedAt()), + + UpdatedAt: utils.NullableString(from.GetUpdatedAt()), + + PullRequest: utils.NullableString(from.GetPullRequest()), + } + }), + + GrantId: utils.NullableString(item.GetGrantId()), + + CreatedAt: utils.NullableString(item.GetCreatedAt()), + + UpdatedAt: utils.NullableString(item.GetUpdatedAt()), + + PullRequest: utils.NullableString(item.GetPullRequest()), + } + } + + dataModel.CreatedAt = utils.NullableString(grantKit.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(grantKit.GetUpdatedAt()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *GrantKitResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var dataModel GrantKitResourceModel + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.Plan.Get) + + if resp.Diagnostics.HasError() { + return + } + + requestBody := grantkits.GrantKitCreateParams{ + Name: dataModel.Name.ValueStringPointer(), + Description: dataModel.Description.ValueStringPointer(), + + Workflow: utils.NullableTfStateObject(dataModel.Workflow, func(from *grant_workflow.GrantWorkflow) grantkits.GrantWorkflow { + return grantkits.GrantWorkflow{ + Steps: utils.MapList(from.Steps, func(from step.Step) grantkits.Step { + return grantkits.Step{ + + Reviewers: utils.NullableTfStateObject(from.Reviewers, func(from *reviewers.Reviewers) grantkits.Reviewers { + return grantkits.Reviewers{ + OneOf: utils.FromListToPrimitiveSlice[string](ctx, from.OneOf, &resp.Diagnostics), + AllOf: utils.FromListToPrimitiveSlice[string](ctx, from.AllOf, &resp.Diagnostics), + } + }), + SkipIf: utils.MapList(from.SkipIf, func(from policy.Policy) grantkits.Policy { + return grantkits.Policy{ + Bundle: from.Bundle.ValueStringPointer(), + Query: from.Query.ValueStringPointer(), + } + }), + } + }), + } + }), + Policies: utils.MapList(dataModel.Policies, func(from policy.Policy) grantkits.Policy { + return grantkits.Policy{ + Bundle: from.Bundle.ValueStringPointer(), + Query: from.Query.ValueStringPointer(), + } + }), + + Output: utils.NullableTfStateObject(dataModel.Output, func(from *output.Output) grantkits.Output { + return grantkits.Output{ + Location: from.Location.ValueStringPointer(), + Append: from.Append.ValueStringPointer(), + Overwrite: from.Overwrite.ValueStringPointer(), + } + }), + } + + clientResponse, err := r.client.GrantKits.CreateGrantKit(ctx, requestBody) + + if err != nil { + resp.Diagnostics.AddError( + "Error Creating GrantKit", + err.Error(), + ) + + return + } + + grantKit := clientResponse.Data + dataModel.Id = utils.NullableString(grantKit.GetId()) + + dataModel.Name = utils.NullableString(grantKit.GetName()) + + dataModel.CurrentVersionId = utils.NullableString(grantKit.GetCurrentVersionId()) + + dataModel.Description = utils.NullableString(grantKit.GetDescription()) + + dataModel.MaxGrantDurationInSec = utils.NullableFloat64(grantKit.GetMaxGrantDurationInSec()) + + if grantKit.Workflow != nil { + dataModel.Workflow = utils.NullableObject(grantKit.Workflow, grant_workflow.GrantWorkflow{ + Steps: utils.MapList(grantKit.GetWorkflow().Steps, func(from grantkits.Step) step.Step { + return step.Step{ + Reviewers: utils.NullableObject(from.Reviewers, reviewers.Reviewers{ + OneOf: utils.ToList(ctx, from.Reviewers.OneOf, types.StringType, &resp.Diagnostics), + + AllOf: utils.ToList(ctx, from.Reviewers.AllOf, types.StringType, &resp.Diagnostics), + }), + + SkipIf: utils.MapList(from.SkipIf, func(from grantkits.Policy) policy.Policy { + return policy.Policy{ + Bundle: utils.NullableString(from.GetBundle()), + + Query: utils.NullableString(from.GetQuery()), + } + }), + } + }), + }) + } + + for index, item := range grantKit.Policies { + dataModel.Policies[index] = policy.Policy{ + Bundle: utils.NullableString(item.GetBundle()), + + Query: utils.NullableString(item.GetQuery()), + } + } + + if grantKit.Output != nil { + dataModel.Output = utils.NullableObject(grantKit.Output, output.Output{ + Location: utils.NullableString(grantKit.GetOutput().GetLocation()), + + Append: utils.NullableString(grantKit.GetOutput().GetAppend()), + + Overwrite: utils.NullableString(grantKit.GetOutput().GetOverwrite()), + }) + } + + for index, item := range grantKit.Grants { + dataModel.Grants[index] = grant.Grant{ + Id: utils.NullableString(item.GetId()), + + GrantKitId: utils.NullableString(item.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(item.GetGrantKitVersionId()), + + UserId: utils.NullableString(item.GetUserId()), + + RequestId: utils.NullableString(item.GetRequestId()), + + OrganizationId: utils.NullableString(item.GetOrganizationId()), + + Deleted: utils.NullableBool(item.GetDeleted()), + + CreatedAt: utils.NullableString(item.GetCreatedAt()), + + UpdatedAt: utils.NullableString(item.GetUpdatedAt()), + } + } + + dataModel.ResourceType = utils.NullableString(grantKit.GetResourceType()) + + for index, item := range grantKit.Requests { + dataModel.Requests[index] = request.Request{ + Id: utils.NullableString(item.GetId()), + + GrantKitId: utils.NullableString(item.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(item.GetGrantKitVersionId()), + + GrantKitName: utils.NullableString(item.GetGrantKitName()), + + Reason: utils.NullableString(item.GetReason()), + + UserId: utils.NullableString(item.GetUserId()), + + Status: types.StringValue(string(*item.GetStatus())), + + Reviews: utils.MapList(item.Reviews, func(from grantkits.Review) review.Review { + return review.Review{ + Id: utils.NullableString(from.GetId()), + + UserId: utils.NullableString(from.GetUserId()), + + UserEmail: utils.NullableString(from.GetUserEmail()), + + RequestId: utils.NullableString(from.GetRequestId()), + + Status: types.StringValue(string(*from.GetStatus())), + + RequestReason: utils.NullableString(from.GetRequestReason()), + + Reason: utils.NullableString(from.GetReason()), + + GrantKitVersionId: utils.NullableString(from.GetGrantKitVersionId()), + + GrantKitName: utils.NullableString(from.GetGrantKitName()), + + GrantId: utils.NullableString(from.GetGrantId()), + + Grant: utils.NullableObject(from.Grant, grant.Grant{ + Id: utils.NullableString(from.Grant.GetId()), + + GrantKitId: utils.NullableString(from.Grant.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(from.Grant.GetGrantKitVersionId()), + + UserId: utils.NullableString(from.Grant.GetUserId()), + + RequestId: utils.NullableString(from.Grant.GetRequestId()), + + OrganizationId: utils.NullableString(from.Grant.GetOrganizationId()), + + Deleted: utils.NullableBool(from.Grant.GetDeleted()), + + CreatedAt: utils.NullableString(from.Grant.GetCreatedAt()), + + UpdatedAt: utils.NullableString(from.Grant.GetUpdatedAt()), + }), + + CreatedAt: utils.NullableString(from.GetCreatedAt()), + + UpdatedAt: utils.NullableString(from.GetUpdatedAt()), + + PullRequest: utils.NullableString(from.GetPullRequest()), + } + }), + + GrantId: utils.NullableString(item.GetGrantId()), + + CreatedAt: utils.NullableString(item.GetCreatedAt()), + + UpdatedAt: utils.NullableString(item.GetUpdatedAt()), + + PullRequest: utils.NullableString(item.GetPullRequest()), + } + } + + dataModel.CreatedAt = utils.NullableString(grantKit.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(grantKit.GetUpdatedAt()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *GrantKitResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var dataModel = &GrantKitResourceModel{} + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.State.Get) + + if resp.Diagnostics.HasError() { + return + } + + GrantKitIdOrName := dataModel.Id.ValueString() + + _, err := r.client.GrantKits.DeleteGrantKit(ctx, GrantKitIdOrName) + + if err != nil { + resp.Diagnostics.AddError( + "Error Deleting GrantKit", + err.Error(), + ) + } +} + +func (r *GrantKitResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var stateModel = &GrantKitResourceModel{} + var dataModel = &GrantKitResourceModel{} + utils.PopulateModelData(ctx, &stateModel, resp.Diagnostics, req.State.Get) + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.Plan.Get) + + if resp.Diagnostics.HasError() { + return + } + + GrantKitIdOrName := stateModel.Id.ValueString() + + requestBody := grantkits.GrantKitUpdateParams{ + Name: dataModel.Name.ValueStringPointer(), + Description: dataModel.Description.ValueStringPointer(), + + Workflow: utils.NullableTfStateObject(dataModel.Workflow, func(from *grant_workflow.GrantWorkflow) grantkits.GrantWorkflow { + return grantkits.GrantWorkflow{ + Steps: utils.MapList(from.Steps, func(from step.Step) grantkits.Step { + return grantkits.Step{ + + Reviewers: utils.NullableTfStateObject(from.Reviewers, func(from *reviewers.Reviewers) grantkits.Reviewers { + return grantkits.Reviewers{ + OneOf: utils.FromListToPrimitiveSlice[string](ctx, from.OneOf, &resp.Diagnostics), + AllOf: utils.FromListToPrimitiveSlice[string](ctx, from.AllOf, &resp.Diagnostics), + } + }), + SkipIf: utils.MapList(from.SkipIf, func(from policy.Policy) grantkits.Policy { + return grantkits.Policy{ + Bundle: from.Bundle.ValueStringPointer(), + Query: from.Query.ValueStringPointer(), + } + }), + } + }), + } + }), + + Output: utils.NullableTfStateObject(dataModel.Output, func(from *output.Output) grantkits.Output { + return grantkits.Output{ + Location: from.Location.ValueStringPointer(), + Append: from.Append.ValueStringPointer(), + Overwrite: from.Overwrite.ValueStringPointer(), + } + }), + Policies: utils.MapList(dataModel.Policies, func(from policy.Policy) grantkits.Policy { + return grantkits.Policy{ + Bundle: from.Bundle.ValueStringPointer(), + Query: from.Query.ValueStringPointer(), + } + }), + } + + clientResponse, err := r.client.GrantKits.UpdateGrantKit(ctx, GrantKitIdOrName, requestBody) + + if err != nil { + resp.Diagnostics.AddError( + "Error updating GrantKit", + err.Error(), + ) + + return + } + grantKit := clientResponse.Data + dataModel.Id = utils.NullableString(grantKit.GetId()) + + dataModel.Name = utils.NullableString(grantKit.GetName()) + + dataModel.CurrentVersionId = utils.NullableString(grantKit.GetCurrentVersionId()) + + dataModel.Description = utils.NullableString(grantKit.GetDescription()) + + dataModel.MaxGrantDurationInSec = utils.NullableFloat64(grantKit.GetMaxGrantDurationInSec()) + + if grantKit.Workflow != nil { + dataModel.Workflow = utils.NullableObject(grantKit.Workflow, grant_workflow.GrantWorkflow{ + Steps: utils.MapList(grantKit.GetWorkflow().Steps, func(from grantkits.Step) step.Step { + return step.Step{ + Reviewers: utils.NullableObject(from.Reviewers, reviewers.Reviewers{ + OneOf: utils.ToList(ctx, from.Reviewers.OneOf, types.StringType, &resp.Diagnostics), + + AllOf: utils.ToList(ctx, from.Reviewers.AllOf, types.StringType, &resp.Diagnostics), + }), + + SkipIf: utils.MapList(from.SkipIf, func(from grantkits.Policy) policy.Policy { + return policy.Policy{ + Bundle: utils.NullableString(from.GetBundle()), + + Query: utils.NullableString(from.GetQuery()), + } + }), + } + }), + }) + } + + for index, item := range grantKit.Policies { + dataModel.Policies[index] = policy.Policy{ + Bundle: utils.NullableString(item.GetBundle()), + + Query: utils.NullableString(item.GetQuery()), + } + } + + if grantKit.Output != nil { + dataModel.Output = utils.NullableObject(grantKit.Output, output.Output{ + Location: utils.NullableString(grantKit.GetOutput().GetLocation()), + + Append: utils.NullableString(grantKit.GetOutput().GetAppend()), + + Overwrite: utils.NullableString(grantKit.GetOutput().GetOverwrite()), + }) + } + + for index, item := range grantKit.Grants { + dataModel.Grants[index] = grant.Grant{ + Id: utils.NullableString(item.GetId()), + + GrantKitId: utils.NullableString(item.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(item.GetGrantKitVersionId()), + + UserId: utils.NullableString(item.GetUserId()), + + RequestId: utils.NullableString(item.GetRequestId()), + + OrganizationId: utils.NullableString(item.GetOrganizationId()), + + Deleted: utils.NullableBool(item.GetDeleted()), + + CreatedAt: utils.NullableString(item.GetCreatedAt()), + + UpdatedAt: utils.NullableString(item.GetUpdatedAt()), + } + } + + dataModel.ResourceType = utils.NullableString(grantKit.GetResourceType()) + + for index, item := range grantKit.Requests { + dataModel.Requests[index] = request.Request{ + Id: utils.NullableString(item.GetId()), + + GrantKitId: utils.NullableString(item.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(item.GetGrantKitVersionId()), + + GrantKitName: utils.NullableString(item.GetGrantKitName()), + + Reason: utils.NullableString(item.GetReason()), + + UserId: utils.NullableString(item.GetUserId()), + + Status: types.StringValue(string(*item.GetStatus())), + + Reviews: utils.MapList(item.Reviews, func(from grantkits.Review) review.Review { + return review.Review{ + Id: utils.NullableString(from.GetId()), + + UserId: utils.NullableString(from.GetUserId()), + + UserEmail: utils.NullableString(from.GetUserEmail()), + + RequestId: utils.NullableString(from.GetRequestId()), + + Status: types.StringValue(string(*from.GetStatus())), + + RequestReason: utils.NullableString(from.GetRequestReason()), + + Reason: utils.NullableString(from.GetReason()), + + GrantKitVersionId: utils.NullableString(from.GetGrantKitVersionId()), + + GrantKitName: utils.NullableString(from.GetGrantKitName()), + + GrantId: utils.NullableString(from.GetGrantId()), + + Grant: utils.NullableObject(from.Grant, grant.Grant{ + Id: utils.NullableString(from.Grant.GetId()), + + GrantKitId: utils.NullableString(from.Grant.GetGrantKitId()), + + GrantKitVersionId: utils.NullableString(from.Grant.GetGrantKitVersionId()), + + UserId: utils.NullableString(from.Grant.GetUserId()), + + RequestId: utils.NullableString(from.Grant.GetRequestId()), + + OrganizationId: utils.NullableString(from.Grant.GetOrganizationId()), + + Deleted: utils.NullableBool(from.Grant.GetDeleted()), + + CreatedAt: utils.NullableString(from.Grant.GetCreatedAt()), + + UpdatedAt: utils.NullableString(from.Grant.GetUpdatedAt()), + }), + + CreatedAt: utils.NullableString(from.GetCreatedAt()), + + UpdatedAt: utils.NullableString(from.GetUpdatedAt()), + + PullRequest: utils.NullableString(from.GetPullRequest()), + } + }), + + GrantId: utils.NullableString(item.GetGrantId()), + + CreatedAt: utils.NullableString(item.GetCreatedAt()), + + UpdatedAt: utils.NullableString(item.GetUpdatedAt()), + + PullRequest: utils.NullableString(item.GetPullRequest()), + } + } + + dataModel.CreatedAt = utils.NullableString(grantKit.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(grantKit.GetUpdatedAt()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *GrantKitResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + // Retrieve import ID and save to id attribute + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} diff --git a/internal/provider/grantkit/resource_test.go b/internal/provider/grantkit/resource_test.go new file mode 100644 index 0000000..fbc28f9 --- /dev/null +++ b/internal/provider/grantkit/resource_test.go @@ -0,0 +1,39 @@ +//go:build unit +// +build unit + +package grantkit + +import ( + "context" + "github.com/go-provider-sdk/pkg/client" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestConfigureResource(t *testing.T) { + // mock client + mockClient := &client.Client{} + + // create GrantKitResource instance + resourceInstance := NewGrantKitResource() + + // Type-assert to the concrete type + r, ok := resourceInstance.(*GrantKitResource) + if !ok { + t.Fatalf("Failed to type assert resourceInstance to *GrantKitResource") + } + + // create mock ConfigureRequest + req := resource.ConfigureRequest{ + ProviderData: mockClient, + } + + var resp resource.ConfigureResponse + + r.Configure(context.Background(), req, &resp) + + // assertions + assert.False(t, resp.Diagnostics.HasError()) + assert.Equal(t, mockClient, r.client, "Expected client to be set correctly in GrantKitResource") +} diff --git a/internal/provider/grantkit_data_source.go b/internal/provider/grantkit_data_source.go deleted file mode 100755 index ad38499..0000000 --- a/internal/provider/grantkit_data_source.go +++ /dev/null @@ -1,408 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk" - "abbey/v2/internal/sdk/pkg/models/operations" - "context" - "fmt" - - "abbey/v2/internal/validators" - "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" -) - -// Ensure provider defined types fully satisfy framework interfaces. -var _ datasource.DataSource = &GrantKitDataSource{} -var _ datasource.DataSourceWithConfigure = &GrantKitDataSource{} - -func NewGrantKitDataSource() datasource.DataSource { - return &GrantKitDataSource{} -} - -// GrantKitDataSource is the data source implementation. -type GrantKitDataSource struct { - client *sdk.SDK -} - -// GrantKitDataSourceModel describes the data model. -type GrantKitDataSourceModel struct { - CreatedAt types.String `tfsdk:"created_at"` - CurrentVersionID types.String `tfsdk:"current_version_id"` - Description types.String `tfsdk:"description"` - Grants []Grant `tfsdk:"grants"` - ID types.String `tfsdk:"id"` - Name types.String `tfsdk:"name"` - Output Output `tfsdk:"output"` - Policies []Policy `tfsdk:"policies"` - Requests []Request `tfsdk:"requests"` - UpdatedAt types.String `tfsdk:"updated_at"` - Workflow *GrantWorkflow `tfsdk:"workflow"` -} - -// Metadata returns the data source type name. -func (r *GrantKitDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_grant_kit" -} - -// Schema defines the schema for the data source. -func (r *GrantKitDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { - resp.Schema = schema.Schema{ - MarkdownDescription: "GrantKit DataSource", - - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "current_version_id": schema.StringAttribute{ - Computed: true, - }, - "description": schema.StringAttribute{ - Computed: true, - }, - "grants": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "deleted": schema.BoolAttribute{ - Computed: true, - }, - "grant_kit_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "organization_id": schema.StringAttribute{ - Computed: true, - }, - "request_id": schema.StringAttribute{ - Computed: true, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - "id": schema.StringAttribute{ - Required: true, - Description: `The ID of the grant kit or resource to retrieve.`, - }, - "name": schema.StringAttribute{ - Computed: true, - }, - "output": schema.SingleNestedAttribute{ - Computed: true, - Attributes: map[string]schema.Attribute{ - "append": schema.StringAttribute{ - Computed: true, - }, - "location": schema.StringAttribute{ - Computed: true, - }, - "overwrite": schema.StringAttribute{ - Computed: true, - }, - }, - }, - "policies": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "bundle": schema.StringAttribute{ - Computed: true, - }, - "query": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - "requests": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "grant_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_name": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "pull_request": schema.StringAttribute{ - Computed: true, - }, - "reason": schema.StringAttribute{ - Computed: true, - }, - "reviews": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "grant": schema.SingleNestedAttribute{ - Computed: true, - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "deleted": schema.BoolAttribute{ - Computed: true, - }, - "grant_kit_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "organization_id": schema.StringAttribute{ - Computed: true, - }, - "request_id": schema.StringAttribute{ - Computed: true, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - Description: `Success`, - }, - "grant_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_name": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "pull_request": schema.StringAttribute{ - Computed: true, - }, - "reason": schema.StringAttribute{ - Computed: true, - }, - "request_id": schema.StringAttribute{ - Computed: true, - }, - "status": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - stringvalidator.OneOf( - "Pending", - "Denied", - "Approved", - "Canceled", - ), - }, - Description: `must be one of [Pending, Denied, Approved, Canceled]`, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_email": schema.StringAttribute{ - Computed: true, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - "status": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - stringvalidator.OneOf( - "Pending", - "Denied", - "Approved", - "Canceled", - ), - }, - Description: `must be one of [Pending, Denied, Approved, Canceled]`, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "workflow": schema.SingleNestedAttribute{ - Computed: true, - Attributes: map[string]schema.Attribute{ - "steps": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "reviewers": schema.SingleNestedAttribute{ - Computed: true, - Attributes: map[string]schema.Attribute{ - "all_of": schema.ListAttribute{ - Computed: true, - ElementType: types.StringType, - }, - "one_of": schema.ListAttribute{ - Computed: true, - ElementType: types.StringType, - }, - }, - }, - "skip_if": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "bundle": schema.StringAttribute{ - Computed: true, - }, - "query": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } -} - -func (r *GrantKitDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { - // Prevent panic if the provider has not been configured. - if req.ProviderData == nil { - return - } - - client, ok := req.ProviderData.(*sdk.SDK) - - if !ok { - resp.Diagnostics.AddError( - "Unexpected DataSource Configure Type", - fmt.Sprintf("Expected *sdk.SDK, got: %T. Please report this issue to the provider developers.", req.ProviderData), - ) - - return - } - - r.client = client -} - -func (r *GrantKitDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data *GrantKitDataSourceModel - var item types.Object - - resp.Diagnostics.Append(req.Config.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - grantKitIDOrName := data.ID.ValueString() - request := operations.GetGrantKitByIDRequest{ - GrantKitIDOrName: grantKitIDOrName, - } - res, err := r.client.GrantKits.GetGrantKitByID(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.GrantKit == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromGetResponse(res.GrantKit) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} diff --git a/internal/provider/grantkit_data_source_sdk.go b/internal/provider/grantkit_data_source_sdk.go deleted file mode 100755 index 2fe38bb..0000000 --- a/internal/provider/grantkit_data_source_sdk.go +++ /dev/null @@ -1,160 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "github.com/hashicorp/terraform-plugin-framework/types" - "time" -) - -func (r *GrantKitDataSourceModel) RefreshFromGetResponse(resp *shared.GrantKit) { - r.CreatedAt = types.StringValue(resp.CreatedAt.Format(time.RFC3339)) - r.CurrentVersionID = types.StringValue(resp.CurrentVersionID) - r.Description = types.StringValue(resp.Description) - r.Grants = nil - for _, grantsItem := range resp.Grants { - var grants1 Grant - grants1.CreatedAt = types.StringValue(grantsItem.CreatedAt.Format(time.RFC3339)) - grants1.Deleted = types.BoolValue(grantsItem.Deleted) - grants1.GrantKitID = types.StringValue(grantsItem.GrantKitID) - grants1.GrantKitVersionID = types.StringValue(grantsItem.GrantKitVersionID) - grants1.ID = types.StringValue(grantsItem.ID) - grants1.OrganizationID = types.StringValue(grantsItem.OrganizationID) - grants1.RequestID = types.StringValue(grantsItem.RequestID) - grants1.UpdatedAt = types.StringValue(grantsItem.UpdatedAt.Format(time.RFC3339)) - grants1.UserID = types.StringValue(grantsItem.UserID) - r.Grants = append(r.Grants, grants1) - } - r.ID = types.StringValue(resp.ID) - r.Name = types.StringValue(resp.Name) - if resp.Output.Append != nil { - r.Output.Append = types.StringValue(*resp.Output.Append) - } else { - r.Output.Append = types.StringNull() - } - r.Output.Location = types.StringValue(resp.Output.Location) - if resp.Output.Overwrite != nil { - r.Output.Overwrite = types.StringValue(*resp.Output.Overwrite) - } else { - r.Output.Overwrite = types.StringNull() - } - r.Policies = nil - for _, policiesItem := range resp.Policies { - var policies1 Policy - if policiesItem.Bundle != nil { - policies1.Bundle = types.StringValue(*policiesItem.Bundle) - } else { - policies1.Bundle = types.StringNull() - } - if policiesItem.Query != nil { - policies1.Query = types.StringValue(*policiesItem.Query) - } else { - policies1.Query = types.StringNull() - } - r.Policies = append(r.Policies, policies1) - } - r.Requests = nil - for _, requestsItem := range resp.Requests { - var requests1 Request - requests1.CreatedAt = types.StringValue(requestsItem.CreatedAt.Format(time.RFC3339)) - requests1.GrantID = types.StringValue(requestsItem.GrantID) - requests1.GrantKitID = types.StringValue(requestsItem.GrantKitID) - if requestsItem.GrantKitName != nil { - requests1.GrantKitName = types.StringValue(*requestsItem.GrantKitName) - } else { - requests1.GrantKitName = types.StringNull() - } - requests1.GrantKitVersionID = types.StringValue(requestsItem.GrantKitVersionID) - requests1.ID = types.StringValue(requestsItem.ID) - requests1.PullRequest = types.StringValue(requestsItem.PullRequest) - requests1.Reason = types.StringValue(requestsItem.Reason) - requests1.Reviews = nil - for _, reviewsItem := range requestsItem.Reviews { - var reviews1 Review - reviews1.CreatedAt = types.StringValue(reviewsItem.CreatedAt.Format(time.RFC3339)) - if reviews1.Grant == nil { - reviews1.Grant = &Grant{} - } - if reviewsItem.Grant == nil { - reviews1.Grant = nil - } else { - reviews1.Grant = &Grant{} - reviews1.Grant.CreatedAt = types.StringValue(reviewsItem.Grant.CreatedAt.Format(time.RFC3339)) - reviews1.Grant.Deleted = types.BoolValue(reviewsItem.Grant.Deleted) - reviews1.Grant.GrantKitID = types.StringValue(reviewsItem.Grant.GrantKitID) - reviews1.Grant.GrantKitVersionID = types.StringValue(reviewsItem.Grant.GrantKitVersionID) - reviews1.Grant.ID = types.StringValue(reviewsItem.Grant.ID) - reviews1.Grant.OrganizationID = types.StringValue(reviewsItem.Grant.OrganizationID) - reviews1.Grant.RequestID = types.StringValue(reviewsItem.Grant.RequestID) - reviews1.Grant.UpdatedAt = types.StringValue(reviewsItem.Grant.UpdatedAt.Format(time.RFC3339)) - reviews1.Grant.UserID = types.StringValue(reviewsItem.Grant.UserID) - } - reviews1.GrantID = types.StringValue(reviewsItem.GrantID) - reviews1.GrantKitName = types.StringValue(reviewsItem.GrantKitName) - reviews1.GrantKitVersionID = types.StringValue(reviewsItem.GrantKitVersionID) - reviews1.ID = types.StringValue(reviewsItem.ID) - reviews1.PullRequest = types.StringValue(reviewsItem.PullRequest) - reviews1.Reason = types.StringValue(reviewsItem.Reason) - reviews1.RequestID = types.StringValue(reviewsItem.RequestID) - reviews1.Status = types.StringValue(string(reviewsItem.Status)) - reviews1.UpdatedAt = types.StringValue(reviewsItem.UpdatedAt.Format(time.RFC3339)) - if reviewsItem.UserEmail != nil { - reviews1.UserEmail = types.StringValue(*reviewsItem.UserEmail) - } else { - reviews1.UserEmail = types.StringNull() - } - reviews1.UserID = types.StringValue(reviewsItem.UserID) - requests1.Reviews = append(requests1.Reviews, reviews1) - } - requests1.Status = types.StringValue(string(requestsItem.Status)) - requests1.UpdatedAt = types.StringValue(requestsItem.UpdatedAt.Format(time.RFC3339)) - requests1.UserID = types.StringValue(requestsItem.UserID) - r.Requests = append(r.Requests, requests1) - } - r.UpdatedAt = types.StringValue(resp.UpdatedAt.Format(time.RFC3339)) - if r.Workflow == nil { - r.Workflow = &GrantWorkflow{} - } - if resp.Workflow == nil { - r.Workflow = nil - } else { - r.Workflow = &GrantWorkflow{} - r.Workflow.Steps = nil - for _, stepsItem := range resp.Workflow.Steps { - var steps1 Step - if steps1.Reviewers == nil { - steps1.Reviewers = &Reviewers{} - } - if stepsItem.Reviewers == nil { - steps1.Reviewers = nil - } else { - steps1.Reviewers = &Reviewers{} - steps1.Reviewers.AllOf = nil - for _, v := range stepsItem.Reviewers.AllOf { - steps1.Reviewers.AllOf = append(steps1.Reviewers.AllOf, types.StringValue(v)) - } - steps1.Reviewers.OneOf = nil - for _, v := range stepsItem.Reviewers.OneOf { - steps1.Reviewers.OneOf = append(steps1.Reviewers.OneOf, types.StringValue(v)) - } - } - steps1.SkipIf = nil - for _, skipIfItem := range stepsItem.SkipIf { - var skipIf1 Policy - if skipIfItem.Bundle != nil { - skipIf1.Bundle = types.StringValue(*skipIfItem.Bundle) - } else { - skipIf1.Bundle = types.StringNull() - } - if skipIfItem.Query != nil { - skipIf1.Query = types.StringValue(*skipIfItem.Query) - } else { - skipIf1.Query = types.StringNull() - } - steps1.SkipIf = append(steps1.SkipIf, skipIf1) - } - r.Workflow.Steps = append(r.Workflow.Steps, steps1) - } - } -} diff --git a/internal/provider/grantkit_resource.go b/internal/provider/grantkit_resource.go deleted file mode 100755 index 7aed9a7..0000000 --- a/internal/provider/grantkit_resource.go +++ /dev/null @@ -1,537 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk" - "context" - "fmt" - - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/validators" - "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" -) - -// Ensure provider defined types fully satisfy framework interfaces. -var _ resource.Resource = &GrantKitResource{} -var _ resource.ResourceWithImportState = &GrantKitResource{} - -func NewGrantKitResource() resource.Resource { - return &GrantKitResource{} -} - -// GrantKitResource defines the resource implementation. -type GrantKitResource struct { - client *sdk.SDK -} - -// GrantKitResourceModel describes the resource data model. -type GrantKitResourceModel struct { - CreatedAt types.String `tfsdk:"created_at"` - CurrentVersionID types.String `tfsdk:"current_version_id"` - Description types.String `tfsdk:"description"` - Grants []Grant `tfsdk:"grants"` - ID types.String `tfsdk:"id"` - Name types.String `tfsdk:"name"` - Output Output `tfsdk:"output"` - Policies []Policy `tfsdk:"policies"` - Requests []Request `tfsdk:"requests"` - UpdatedAt types.String `tfsdk:"updated_at"` - Workflow *GrantWorkflow `tfsdk:"workflow"` -} - -func (r *GrantKitResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_grant_kit" -} - -func (r *GrantKitResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - resp.Schema = schema.Schema{ - MarkdownDescription: "GrantKit Resource", - - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "current_version_id": schema.StringAttribute{ - Computed: true, - }, - "description": schema.StringAttribute{ - Required: true, - }, - "grants": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "deleted": schema.BoolAttribute{ - Computed: true, - }, - "grant_kit_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "organization_id": schema.StringAttribute{ - Computed: true, - }, - "request_id": schema.StringAttribute{ - Computed: true, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "name": schema.StringAttribute{ - Required: true, - }, - "output": schema.SingleNestedAttribute{ - Required: true, - Attributes: map[string]schema.Attribute{ - "append": schema.StringAttribute{ - Computed: true, - Optional: true, - }, - "location": schema.StringAttribute{ - Required: true, - }, - "overwrite": schema.StringAttribute{ - Computed: true, - Optional: true, - }, - }, - }, - "policies": schema.ListNestedAttribute{ - Optional: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "bundle": schema.StringAttribute{ - Computed: true, - Optional: true, - }, - "query": schema.StringAttribute{ - Computed: true, - Optional: true, - }, - }, - }, - }, - "requests": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "grant_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_name": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "pull_request": schema.StringAttribute{ - Computed: true, - }, - "reason": schema.StringAttribute{ - Computed: true, - }, - "reviews": schema.ListNestedAttribute{ - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "grant": schema.SingleNestedAttribute{ - Computed: true, - Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "deleted": schema.BoolAttribute{ - Computed: true, - }, - "grant_kit_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "organization_id": schema.StringAttribute{ - Computed: true, - }, - "request_id": schema.StringAttribute{ - Computed: true, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - Description: `Success`, - }, - "grant_id": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_name": schema.StringAttribute{ - Computed: true, - }, - "grant_kit_version_id": schema.StringAttribute{ - Computed: true, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "pull_request": schema.StringAttribute{ - Computed: true, - }, - "reason": schema.StringAttribute{ - Computed: true, - }, - "request_id": schema.StringAttribute{ - Computed: true, - }, - "status": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - stringvalidator.OneOf( - "Pending", - "Denied", - "Approved", - "Canceled", - ), - }, - Description: `must be one of [Pending, Denied, Approved, Canceled]`, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_email": schema.StringAttribute{ - Computed: true, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - "status": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - stringvalidator.OneOf( - "Pending", - "Denied", - "Approved", - "Canceled", - ), - }, - Description: `must be one of [Pending, Denied, Approved, Canceled]`, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "user_id": schema.StringAttribute{ - Computed: true, - }, - }, - }, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "workflow": schema.SingleNestedAttribute{ - Optional: true, - Attributes: map[string]schema.Attribute{ - "steps": schema.ListNestedAttribute{ - Computed: true, - Optional: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "reviewers": schema.SingleNestedAttribute{ - Computed: true, - Optional: true, - Attributes: map[string]schema.Attribute{ - "all_of": schema.ListAttribute{ - Computed: true, - Optional: true, - ElementType: types.StringType, - }, - "one_of": schema.ListAttribute{ - Computed: true, - Optional: true, - ElementType: types.StringType, - }, - }, - }, - "skip_if": schema.ListNestedAttribute{ - Computed: true, - Optional: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "bundle": schema.StringAttribute{ - Computed: true, - Optional: true, - }, - "query": schema.StringAttribute{ - Computed: true, - Optional: true, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } -} - -func (r *GrantKitResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - // Prevent panic if the provider has not been configured. - if req.ProviderData == nil { - return - } - - client, ok := req.ProviderData.(*sdk.SDK) - - if !ok { - resp.Diagnostics.AddError( - "Unexpected Resource Configure Type", - fmt.Sprintf("Expected *sdk.SDK, got: %T. Please report this issue to the provider developers.", req.ProviderData), - ) - - return - } - - r.client = client -} - -func (r *GrantKitResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data *GrantKitResourceModel - var item types.Object - - resp.Diagnostics.Append(req.Plan.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - request := *data.ToCreateSDKType() - res, err := r.client.GrantKits.CreateGrantKit(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 201 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.GrantKit == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromCreateResponse(res.GrantKit) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *GrantKitResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data *GrantKitResourceModel - var item types.Object - - resp.Diagnostics.Append(req.State.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - grantKitIDOrName := data.ID.ValueString() - request := operations.GetGrantKitByIDRequest{ - GrantKitIDOrName: grantKitIDOrName, - } - res, err := r.client.GrantKits.GetGrantKitByID(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.GrantKit == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromGetResponse(res.GrantKit) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *GrantKitResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data *GrantKitResourceModel - merge(ctx, req, resp, &data) - if resp.Diagnostics.HasError() { - return - } - - grantKitUpdateParams := *data.ToUpdateSDKType() - grantKitIDOrName := data.ID.ValueString() - request := operations.UpdateGrantKitRequest{ - GrantKitUpdateParams: grantKitUpdateParams, - GrantKitIDOrName: grantKitIDOrName, - } - res, err := r.client.GrantKits.UpdateGrantKit(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.GrantKit == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromUpdateResponse(res.GrantKit) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *GrantKitResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var data *GrantKitResourceModel - var item types.Object - - resp.Diagnostics.Append(req.State.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - grantKitIDOrName := data.ID.ValueString() - request := operations.DeleteGrantKitRequest{ - GrantKitIDOrName: grantKitIDOrName, - } - res, err := r.client.GrantKits.DeleteGrantKit(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - -} - -func (r *GrantKitResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} diff --git a/internal/provider/grantkit_resource_sdk.go b/internal/provider/grantkit_resource_sdk.go deleted file mode 100755 index 3dd411b..0000000 --- a/internal/provider/grantkit_resource_sdk.go +++ /dev/null @@ -1,372 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "github.com/hashicorp/terraform-plugin-framework/types" - "time" -) - -func (r *GrantKitResourceModel) ToCreateSDKType() *shared.GrantKitCreateParams { - description := r.Description.ValueString() - name := r.Name.ValueString() - append1 := new(string) - if !r.Output.Append.IsUnknown() && !r.Output.Append.IsNull() { - *append1 = r.Output.Append.ValueString() - } else { - append1 = nil - } - location := r.Output.Location.ValueString() - overwrite := new(string) - if !r.Output.Overwrite.IsUnknown() && !r.Output.Overwrite.IsNull() { - *overwrite = r.Output.Overwrite.ValueString() - } else { - overwrite = nil - } - output := shared.Output{ - Append: append1, - Location: location, - Overwrite: overwrite, - } - var policies []shared.Policy = nil - for _, policiesItem := range r.Policies { - bundle := new(string) - if !policiesItem.Bundle.IsUnknown() && !policiesItem.Bundle.IsNull() { - *bundle = policiesItem.Bundle.ValueString() - } else { - bundle = nil - } - query := new(string) - if !policiesItem.Query.IsUnknown() && !policiesItem.Query.IsNull() { - *query = policiesItem.Query.ValueString() - } else { - query = nil - } - policies = append(policies, shared.Policy{ - Bundle: bundle, - Query: query, - }) - } - var workflow *shared.GrantWorkflow - if r.Workflow != nil { - var steps []shared.Step = nil - for _, stepsItem := range r.Workflow.Steps { - var reviewers *shared.Reviewers - if stepsItem.Reviewers != nil { - var allOf []string = nil - for _, allOfItem := range stepsItem.Reviewers.AllOf { - allOf = append(allOf, allOfItem.ValueString()) - } - var oneOf []string = nil - for _, oneOfItem := range stepsItem.Reviewers.OneOf { - oneOf = append(oneOf, oneOfItem.ValueString()) - } - reviewers = &shared.Reviewers{ - AllOf: allOf, - OneOf: oneOf, - } - } - var skipIf []shared.Policy = nil - for _, skipIfItem := range stepsItem.SkipIf { - bundle1 := new(string) - if !skipIfItem.Bundle.IsUnknown() && !skipIfItem.Bundle.IsNull() { - *bundle1 = skipIfItem.Bundle.ValueString() - } else { - bundle1 = nil - } - query1 := new(string) - if !skipIfItem.Query.IsUnknown() && !skipIfItem.Query.IsNull() { - *query1 = skipIfItem.Query.ValueString() - } else { - query1 = nil - } - skipIf = append(skipIf, shared.Policy{ - Bundle: bundle1, - Query: query1, - }) - } - steps = append(steps, shared.Step{ - Reviewers: reviewers, - SkipIf: skipIf, - }) - } - workflow = &shared.GrantWorkflow{ - Steps: steps, - } - } - out := shared.GrantKitCreateParams{ - Description: description, - Name: name, - Output: output, - Policies: policies, - Workflow: workflow, - } - return &out -} - -func (r *GrantKitResourceModel) ToGetSDKType() *shared.GrantKitCreateParams { - out := r.ToCreateSDKType() - return out -} - -func (r *GrantKitResourceModel) ToUpdateSDKType() *shared.GrantKitUpdateParams { - description := r.Description.ValueString() - name := r.Name.ValueString() - append1 := new(string) - if !r.Output.Append.IsUnknown() && !r.Output.Append.IsNull() { - *append1 = r.Output.Append.ValueString() - } else { - append1 = nil - } - location := r.Output.Location.ValueString() - overwrite := new(string) - if !r.Output.Overwrite.IsUnknown() && !r.Output.Overwrite.IsNull() { - *overwrite = r.Output.Overwrite.ValueString() - } else { - overwrite = nil - } - output := shared.Output{ - Append: append1, - Location: location, - Overwrite: overwrite, - } - var policies []shared.Policy = nil - for _, policiesItem := range r.Policies { - bundle := new(string) - if !policiesItem.Bundle.IsUnknown() && !policiesItem.Bundle.IsNull() { - *bundle = policiesItem.Bundle.ValueString() - } else { - bundle = nil - } - query := new(string) - if !policiesItem.Query.IsUnknown() && !policiesItem.Query.IsNull() { - *query = policiesItem.Query.ValueString() - } else { - query = nil - } - policies = append(policies, shared.Policy{ - Bundle: bundle, - Query: query, - }) - } - var workflow *shared.GrantWorkflow - if r.Workflow != nil { - var steps []shared.Step = nil - for _, stepsItem := range r.Workflow.Steps { - var reviewers *shared.Reviewers - if stepsItem.Reviewers != nil { - var allOf []string = nil - for _, allOfItem := range stepsItem.Reviewers.AllOf { - allOf = append(allOf, allOfItem.ValueString()) - } - var oneOf []string = nil - for _, oneOfItem := range stepsItem.Reviewers.OneOf { - oneOf = append(oneOf, oneOfItem.ValueString()) - } - reviewers = &shared.Reviewers{ - AllOf: allOf, - OneOf: oneOf, - } - } - var skipIf []shared.Policy = nil - for _, skipIfItem := range stepsItem.SkipIf { - bundle1 := new(string) - if !skipIfItem.Bundle.IsUnknown() && !skipIfItem.Bundle.IsNull() { - *bundle1 = skipIfItem.Bundle.ValueString() - } else { - bundle1 = nil - } - query1 := new(string) - if !skipIfItem.Query.IsUnknown() && !skipIfItem.Query.IsNull() { - *query1 = skipIfItem.Query.ValueString() - } else { - query1 = nil - } - skipIf = append(skipIf, shared.Policy{ - Bundle: bundle1, - Query: query1, - }) - } - steps = append(steps, shared.Step{ - Reviewers: reviewers, - SkipIf: skipIf, - }) - } - workflow = &shared.GrantWorkflow{ - Steps: steps, - } - } - out := shared.GrantKitUpdateParams{ - Description: description, - Name: name, - Output: output, - Policies: policies, - Workflow: workflow, - } - return &out -} - -func (r *GrantKitResourceModel) ToDeleteSDKType() *shared.GrantKitCreateParams { - out := r.ToCreateSDKType() - return out -} - -func (r *GrantKitResourceModel) RefreshFromGetResponse(resp *shared.GrantKit) { - r.CreatedAt = types.StringValue(resp.CreatedAt.Format(time.RFC3339)) - r.CurrentVersionID = types.StringValue(resp.CurrentVersionID) - r.Description = types.StringValue(resp.Description) - r.Grants = nil - for _, grantsItem := range resp.Grants { - var grants1 Grant - grants1.CreatedAt = types.StringValue(grantsItem.CreatedAt.Format(time.RFC3339)) - grants1.Deleted = types.BoolValue(grantsItem.Deleted) - grants1.GrantKitID = types.StringValue(grantsItem.GrantKitID) - grants1.GrantKitVersionID = types.StringValue(grantsItem.GrantKitVersionID) - grants1.ID = types.StringValue(grantsItem.ID) - grants1.OrganizationID = types.StringValue(grantsItem.OrganizationID) - grants1.RequestID = types.StringValue(grantsItem.RequestID) - grants1.UpdatedAt = types.StringValue(grantsItem.UpdatedAt.Format(time.RFC3339)) - grants1.UserID = types.StringValue(grantsItem.UserID) - r.Grants = append(r.Grants, grants1) - } - r.ID = types.StringValue(resp.ID) - r.Name = types.StringValue(resp.Name) - if resp.Output.Append != nil { - r.Output.Append = types.StringValue(*resp.Output.Append) - } else { - r.Output.Append = types.StringNull() - } - r.Output.Location = types.StringValue(resp.Output.Location) - if resp.Output.Overwrite != nil { - r.Output.Overwrite = types.StringValue(*resp.Output.Overwrite) - } else { - r.Output.Overwrite = types.StringNull() - } - r.Policies = nil - for _, policiesItem := range resp.Policies { - var policies1 Policy - if policiesItem.Bundle != nil { - policies1.Bundle = types.StringValue(*policiesItem.Bundle) - } else { - policies1.Bundle = types.StringNull() - } - if policiesItem.Query != nil { - policies1.Query = types.StringValue(*policiesItem.Query) - } else { - policies1.Query = types.StringNull() - } - r.Policies = append(r.Policies, policies1) - } - r.Requests = nil - for _, requestsItem := range resp.Requests { - var requests1 Request - requests1.CreatedAt = types.StringValue(requestsItem.CreatedAt.Format(time.RFC3339)) - requests1.GrantID = types.StringValue(requestsItem.GrantID) - requests1.GrantKitID = types.StringValue(requestsItem.GrantKitID) - if requestsItem.GrantKitName != nil { - requests1.GrantKitName = types.StringValue(*requestsItem.GrantKitName) - } else { - requests1.GrantKitName = types.StringNull() - } - requests1.GrantKitVersionID = types.StringValue(requestsItem.GrantKitVersionID) - requests1.ID = types.StringValue(requestsItem.ID) - requests1.PullRequest = types.StringValue(requestsItem.PullRequest) - requests1.Reason = types.StringValue(requestsItem.Reason) - requests1.Reviews = nil - for _, reviewsItem := range requestsItem.Reviews { - var reviews1 Review - reviews1.CreatedAt = types.StringValue(reviewsItem.CreatedAt.Format(time.RFC3339)) - if reviews1.Grant == nil { - reviews1.Grant = &Grant{} - } - if reviewsItem.Grant == nil { - reviews1.Grant = nil - } else { - reviews1.Grant = &Grant{} - reviews1.Grant.CreatedAt = types.StringValue(reviewsItem.Grant.CreatedAt.Format(time.RFC3339)) - reviews1.Grant.Deleted = types.BoolValue(reviewsItem.Grant.Deleted) - reviews1.Grant.GrantKitID = types.StringValue(reviewsItem.Grant.GrantKitID) - reviews1.Grant.GrantKitVersionID = types.StringValue(reviewsItem.Grant.GrantKitVersionID) - reviews1.Grant.ID = types.StringValue(reviewsItem.Grant.ID) - reviews1.Grant.OrganizationID = types.StringValue(reviewsItem.Grant.OrganizationID) - reviews1.Grant.RequestID = types.StringValue(reviewsItem.Grant.RequestID) - reviews1.Grant.UpdatedAt = types.StringValue(reviewsItem.Grant.UpdatedAt.Format(time.RFC3339)) - reviews1.Grant.UserID = types.StringValue(reviewsItem.Grant.UserID) - } - reviews1.GrantID = types.StringValue(reviewsItem.GrantID) - reviews1.GrantKitName = types.StringValue(reviewsItem.GrantKitName) - reviews1.GrantKitVersionID = types.StringValue(reviewsItem.GrantKitVersionID) - reviews1.ID = types.StringValue(reviewsItem.ID) - reviews1.PullRequest = types.StringValue(reviewsItem.PullRequest) - reviews1.Reason = types.StringValue(reviewsItem.Reason) - reviews1.RequestID = types.StringValue(reviewsItem.RequestID) - reviews1.Status = types.StringValue(string(reviewsItem.Status)) - reviews1.UpdatedAt = types.StringValue(reviewsItem.UpdatedAt.Format(time.RFC3339)) - if reviewsItem.UserEmail != nil { - reviews1.UserEmail = types.StringValue(*reviewsItem.UserEmail) - } else { - reviews1.UserEmail = types.StringNull() - } - reviews1.UserID = types.StringValue(reviewsItem.UserID) - requests1.Reviews = append(requests1.Reviews, reviews1) - } - requests1.Status = types.StringValue(string(requestsItem.Status)) - requests1.UpdatedAt = types.StringValue(requestsItem.UpdatedAt.Format(time.RFC3339)) - requests1.UserID = types.StringValue(requestsItem.UserID) - r.Requests = append(r.Requests, requests1) - } - r.UpdatedAt = types.StringValue(resp.UpdatedAt.Format(time.RFC3339)) - if r.Workflow == nil { - r.Workflow = &GrantWorkflow{} - } - if resp.Workflow == nil { - r.Workflow = nil - } else { - r.Workflow = &GrantWorkflow{} - r.Workflow.Steps = nil - for _, stepsItem := range resp.Workflow.Steps { - var steps1 Step - if steps1.Reviewers == nil { - steps1.Reviewers = &Reviewers{} - } - if stepsItem.Reviewers == nil { - steps1.Reviewers = nil - } else { - steps1.Reviewers = &Reviewers{} - steps1.Reviewers.AllOf = nil - for _, v := range stepsItem.Reviewers.AllOf { - steps1.Reviewers.AllOf = append(steps1.Reviewers.AllOf, types.StringValue(v)) - } - steps1.Reviewers.OneOf = nil - for _, v := range stepsItem.Reviewers.OneOf { - steps1.Reviewers.OneOf = append(steps1.Reviewers.OneOf, types.StringValue(v)) - } - } - steps1.SkipIf = nil - for _, skipIfItem := range stepsItem.SkipIf { - var skipIf1 Policy - if skipIfItem.Bundle != nil { - skipIf1.Bundle = types.StringValue(*skipIfItem.Bundle) - } else { - skipIf1.Bundle = types.StringNull() - } - if skipIfItem.Query != nil { - skipIf1.Query = types.StringValue(*skipIfItem.Query) - } else { - skipIf1.Query = types.StringNull() - } - steps1.SkipIf = append(steps1.SkipIf, skipIf1) - } - r.Workflow.Steps = append(r.Workflow.Steps, steps1) - } - } -} - -func (r *GrantKitResourceModel) RefreshFromCreateResponse(resp *shared.GrantKit) { - r.RefreshFromGetResponse(resp) -} - -func (r *GrantKitResourceModel) RefreshFromUpdateResponse(resp *shared.GrantKit) { - r.RefreshFromGetResponse(resp) -} diff --git a/internal/provider/identity/acceptance/resource_e2e_test.go b/internal/provider/identity/acceptance/resource_e2e_test.go new file mode 100644 index 0000000..30f4251 --- /dev/null +++ b/internal/provider/identity/acceptance/resource_e2e_test.go @@ -0,0 +1,120 @@ +//go:build acceptance +// +build acceptance + +package acceptance + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "path" + "testing" + + "abbey/v2/internal/provider" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func getIdentityProviderConfig(serverUrl string) string { + return fmt.Sprintf(` + provider "abbey" { + server_url = "server_url" + bearer_auth = "bearer_auth" +} + + `, serverUrl) +} + +func setupIdentityMockServer() *httptest.Server { + db := make(map[string]*identity.Identity) + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if req.Method == http.MethodGet { + Id := path.Base(req.URL.Path) + identity := db[Id] + data, _ := json.Marshal(identity) + + rw.Write(data) + return + } + if req.Method == http.MethodPost { + id := "id" + + identity := identity.Identity{} + + bodyBytes, _ := io.ReadAll(req.Body) + json.Unmarshal(bodyBytes, &identity) + + identity.SetId(id) + data, _ := json.Marshal(identity) + + db[id] = &identity + + rw.Write(data) + return + } + if req.Method == http.MethodPatch || req.Method == http.MethodPut { + identityId := path.Base(req.URL.Path) + + if db[identityId] == nil { + rw.Write([]byte("Error")) + return + } + + identity := identity.Identity{} + + bodyBytes, _ := io.ReadAll(req.Body) + json.Unmarshal(bodyBytes, &identity) + + identity.SetId(identityId) + data, _ := json.Marshal(identity) + + db[identityId] = &identity + + rw.Write(data) + return + } + })) + + return server +} + +func TestAccabbeyIdentityResource(t *testing.T) { + testAccProtoV6ProviderFactories := map[string]func() (tfprotov6.ProviderServer, error){ + "abbey": providerserver.NewProtocol6WithError(provider.New("test")()), + } + + server := setupIdentityMockServer() + defer server.Close() + providerConfig := getIdentityProviderConfig(server.URL) + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read + { + Config: providerConfig + + ` +resource "abbey_identity" "example" { + abbey_account = "abbey_account" + + source = "source" + + metadata = "metadata" + +} + +`, + Check: resource.ComposeAggregateTestCheckFunc( + // Extend this based on the model attributes + resource.TestCheckResourceAttr("abbey_identity.example", "identity_id", "identity_id"), + resource.TestCheckResourceAttr("abbey_identity.example", "abbey_account", "abbey_account"), + resource.TestCheckResourceAttr("abbey_identity.example", "source", "source"), + resource.TestCheckResourceAttr("abbey_identity.example", "metadata", "metadata"), + ), + }, + }, + }) +} diff --git a/internal/provider/identity/resource.go b/internal/provider/identity/resource.go new file mode 100644 index 0000000..76c80f0 --- /dev/null +++ b/internal/provider/identity/resource.go @@ -0,0 +1,258 @@ +package identity + +import ( + "abbey/v2/internal/utils" + "context" + "fmt" + "github.com/go-provider-sdk/pkg/client" + "github.com/go-provider-sdk/pkg/identities" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// ensure we implement the needed interfaces +var _ resource.Resource = &IdentityResource{} +var _ resource.ResourceWithImportState = &IdentityResource{} + +// constructor +func NewIdentityResource() resource.Resource { + return &IdentityResource{} +} + +// client wrapper +type IdentityResource struct { + client *client.Client +} + +type IdentityResourceModel struct { + Id types.String `tfsdk:"id"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` + AbbeyAccount types.String `tfsdk:"abbey_account"` + Source types.String `tfsdk:"source"` + Metadata types.String `tfsdk:"metadata"` +} + +func (r *IdentityResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_identity" +} + +func (r *IdentityResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "id", + Computed: true, + Optional: true, + }, + + "created_at": schema.StringAttribute{ + Description: "created_at", + Computed: true, + Optional: true, + }, + + "updated_at": schema.StringAttribute{ + Description: "updated_at", + Computed: true, + Optional: true, + }, + + "abbey_account": schema.StringAttribute{ + Description: "abbey_account", + Required: true, + }, + + "source": schema.StringAttribute{ + Description: "source", + Required: true, + }, + + "metadata": schema.StringAttribute{ + Description: "Json encoded string. See documentation for details.", + Required: true, + }, + }, + } +} + +func (r *IdentityResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + apiClient, ok := req.ProviderData.(*client.Client) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + r.client = apiClient +} + +func (r *IdentityResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var dataModel IdentityResourceModel + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.State.Get) + + if resp.Diagnostics.HasError() { + return + } + + IdentityId := dataModel.Id.ValueString() + + clientResponse, err := r.client.Identities.GetIdentity(ctx, IdentityId) + if err != nil { + resp.Diagnostics.AddError( + "Unexpected error calling Identities.GetIdentity", + err.Error(), + ) + + return + } + + identity := clientResponse.Data + + dataModel.Id = utils.NullableString(identity.GetId()) + + dataModel.CreatedAt = utils.NullableString(identity.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(identity.GetUpdatedAt()) + + dataModel.AbbeyAccount = utils.NullableString(identity.GetAbbeyAccount()) + + dataModel.Source = utils.NullableString(identity.GetSource()) + + dataModel.Metadata = utils.NullableString(identity.GetMetadata()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *IdentityResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var dataModel IdentityResourceModel + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.Plan.Get) + + if resp.Diagnostics.HasError() { + return + } + + requestBody := identities.IdentityParams{ + AbbeyAccount: dataModel.AbbeyAccount.ValueStringPointer(), + Source: dataModel.Source.ValueStringPointer(), + Metadata: dataModel.Metadata.ValueStringPointer(), + } + + clientResponse, err := r.client.Identities.CreateIdentity(ctx, requestBody) + + if err != nil { + resp.Diagnostics.AddError( + "Error Creating Identity", + err.Error(), + ) + + return + } + + identity := clientResponse.Data + dataModel.Id = utils.NullableString(identity.GetId()) + + dataModel.CreatedAt = utils.NullableString(identity.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(identity.GetUpdatedAt()) + + dataModel.AbbeyAccount = utils.NullableString(identity.GetAbbeyAccount()) + + dataModel.Source = utils.NullableString(identity.GetSource()) + + dataModel.Metadata = utils.NullableString(identity.GetMetadata()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *IdentityResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var dataModel = &IdentityResourceModel{} + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.State.Get) + + if resp.Diagnostics.HasError() { + return + } + + IdentityId := dataModel.Id.ValueString() + + _, err := r.client.Identities.DeleteIdentity(ctx, IdentityId) + + if err != nil { + resp.Diagnostics.AddError( + "Error Deleting Identity", + err.Error(), + ) + } +} + +func (r *IdentityResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var stateModel = &IdentityResourceModel{} + var dataModel = &IdentityResourceModel{} + utils.PopulateModelData(ctx, &stateModel, resp.Diagnostics, req.State.Get) + utils.PopulateModelData(ctx, &dataModel, resp.Diagnostics, req.Plan.Get) + + if resp.Diagnostics.HasError() { + return + } + + IdentityId := stateModel.Id.ValueString() + + requestBody := identities.IdentityParams{ + AbbeyAccount: dataModel.AbbeyAccount.ValueStringPointer(), + Source: dataModel.Source.ValueStringPointer(), + Metadata: dataModel.Metadata.ValueStringPointer(), + } + + clientResponse, err := r.client.Identities.UpdateIdentity(ctx, IdentityId, requestBody) + + if err != nil { + resp.Diagnostics.AddError( + "Error updating Identity", + err.Error(), + ) + + return + } + identity := clientResponse.Data + dataModel.Id = utils.NullableString(identity.GetId()) + + dataModel.CreatedAt = utils.NullableString(identity.GetCreatedAt()) + + dataModel.UpdatedAt = utils.NullableString(identity.GetUpdatedAt()) + + dataModel.AbbeyAccount = utils.NullableString(identity.GetAbbeyAccount()) + + dataModel.Source = utils.NullableString(identity.GetSource()) + + dataModel.Metadata = utils.NullableString(identity.GetMetadata()) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &dataModel)...) +} + +func (r *IdentityResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + // Retrieve import ID and save to id attribute + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} diff --git a/internal/provider/identity/resource_test.go b/internal/provider/identity/resource_test.go new file mode 100644 index 0000000..375307d --- /dev/null +++ b/internal/provider/identity/resource_test.go @@ -0,0 +1,39 @@ +//go:build unit +// +build unit + +package identity + +import ( + "context" + "github.com/go-provider-sdk/pkg/client" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestConfigureResource(t *testing.T) { + // mock client + mockClient := &client.Client{} + + // create IdentityResource instance + resourceInstance := NewIdentityResource() + + // Type-assert to the concrete type + r, ok := resourceInstance.(*IdentityResource) + if !ok { + t.Fatalf("Failed to type assert resourceInstance to *IdentityResource") + } + + // create mock ConfigureRequest + req := resource.ConfigureRequest{ + ProviderData: mockClient, + } + + var resp resource.ConfigureResponse + + r.Configure(context.Background(), req, &resp) + + // assertions + assert.False(t, resp.Diagnostics.HasError()) + assert.Equal(t, mockClient, r.client, "Expected client to be set correctly in IdentityResource") +} diff --git a/internal/provider/identity_data_source.go b/internal/provider/identity_data_source.go deleted file mode 100755 index 38736ed..0000000 --- a/internal/provider/identity_data_source.go +++ /dev/null @@ -1,146 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk" - "abbey/v2/internal/sdk/pkg/models/operations" - "context" - "fmt" - - "abbey/v2/internal/validators" - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" -) - -// Ensure provider defined types fully satisfy framework interfaces. -var _ datasource.DataSource = &IdentityDataSource{} -var _ datasource.DataSourceWithConfigure = &IdentityDataSource{} - -func NewIdentityDataSource() datasource.DataSource { - return &IdentityDataSource{} -} - -// IdentityDataSource is the data source implementation. -type IdentityDataSource struct { - client *sdk.SDK -} - -// IdentityDataSourceModel describes the data model. -type IdentityDataSourceModel struct { - AbbeyAccount types.String `tfsdk:"abbey_account"` - CreatedAt types.String `tfsdk:"created_at"` - ID types.String `tfsdk:"id"` - Metadata types.String `tfsdk:"metadata"` - Source types.String `tfsdk:"source"` - UpdatedAt types.String `tfsdk:"updated_at"` -} - -// Metadata returns the data source type name. -func (r *IdentityDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_identity" -} - -// Schema defines the schema for the data source. -func (r *IdentityDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { - resp.Schema = schema.Schema{ - MarkdownDescription: "Identity DataSource", - - Attributes: map[string]schema.Attribute{ - "abbey_account": schema.StringAttribute{ - Computed: true, - }, - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "id": schema.StringAttribute{ - Required: true, - Description: `The ID of the identity to retrieve`, - }, - "metadata": schema.StringAttribute{ - Computed: true, - Description: `Json encoded string. See documentation for details.`, - }, - "source": schema.StringAttribute{ - Computed: true, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - }, - } -} - -func (r *IdentityDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { - // Prevent panic if the provider has not been configured. - if req.ProviderData == nil { - return - } - - client, ok := req.ProviderData.(*sdk.SDK) - - if !ok { - resp.Diagnostics.AddError( - "Unexpected DataSource Configure Type", - fmt.Sprintf("Expected *sdk.SDK, got: %T. Please report this issue to the provider developers.", req.ProviderData), - ) - - return - } - - r.client = client -} - -func (r *IdentityDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data *IdentityDataSourceModel - var item types.Object - - resp.Diagnostics.Append(req.Config.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - identityID := data.ID.ValueString() - request := operations.GetIdentityRequest{ - IdentityID: identityID, - } - res, err := r.client.Identities.GetIdentity(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.Identity == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromGetResponse(res.Identity) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} diff --git a/internal/provider/identity_data_source_sdk.go b/internal/provider/identity_data_source_sdk.go deleted file mode 100755 index ed453f4..0000000 --- a/internal/provider/identity_data_source_sdk.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "github.com/hashicorp/terraform-plugin-framework/types" - "time" -) - -func (r *IdentityDataSourceModel) RefreshFromGetResponse(resp *shared.Identity) { - r.AbbeyAccount = types.StringValue(resp.AbbeyAccount) - r.CreatedAt = types.StringValue(resp.CreatedAt.Format(time.RFC3339)) - r.ID = types.StringValue(resp.ID) - r.Metadata = types.StringValue(resp.Metadata) - r.Source = types.StringValue(resp.Source) - r.UpdatedAt = types.StringValue(resp.UpdatedAt.Format(time.RFC3339)) -} diff --git a/internal/provider/identity_resource.go b/internal/provider/identity_resource.go deleted file mode 100755 index 65ca10f..0000000 --- a/internal/provider/identity_resource.go +++ /dev/null @@ -1,264 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk" - "context" - "fmt" - - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/validators" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" -) - -// Ensure provider defined types fully satisfy framework interfaces. -var _ resource.Resource = &IdentityResource{} -var _ resource.ResourceWithImportState = &IdentityResource{} - -func NewIdentityResource() resource.Resource { - return &IdentityResource{} -} - -// IdentityResource defines the resource implementation. -type IdentityResource struct { - client *sdk.SDK -} - -// IdentityResourceModel describes the resource data model. -type IdentityResourceModel struct { - AbbeyAccount types.String `tfsdk:"abbey_account"` - CreatedAt types.String `tfsdk:"created_at"` - ID types.String `tfsdk:"id"` - Metadata types.String `tfsdk:"metadata"` - Source types.String `tfsdk:"source"` - UpdatedAt types.String `tfsdk:"updated_at"` -} - -func (r *IdentityResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_identity" -} - -func (r *IdentityResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - resp.Schema = schema.Schema{ - MarkdownDescription: "Identity Resource", - - Attributes: map[string]schema.Attribute{ - "abbey_account": schema.StringAttribute{ - Required: true, - }, - "created_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - "id": schema.StringAttribute{ - Computed: true, - }, - "metadata": schema.StringAttribute{ - Required: true, - Description: `Json encoded string. See documentation for details.`, - }, - "source": schema.StringAttribute{ - Required: true, - }, - "updated_at": schema.StringAttribute{ - Computed: true, - Validators: []validator.String{ - validators.IsRFC3339(), - }, - }, - }, - } -} - -func (r *IdentityResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - // Prevent panic if the provider has not been configured. - if req.ProviderData == nil { - return - } - - client, ok := req.ProviderData.(*sdk.SDK) - - if !ok { - resp.Diagnostics.AddError( - "Unexpected Resource Configure Type", - fmt.Sprintf("Expected *sdk.SDK, got: %T. Please report this issue to the provider developers.", req.ProviderData), - ) - - return - } - - r.client = client -} - -func (r *IdentityResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data *IdentityResourceModel - var item types.Object - - resp.Diagnostics.Append(req.Plan.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - request := *data.ToCreateSDKType() - res, err := r.client.Identities.CreateIdentity(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 201 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.Identity == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromCreateResponse(res.Identity) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *IdentityResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data *IdentityResourceModel - var item types.Object - - resp.Diagnostics.Append(req.State.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - identityID := data.ID.ValueString() - request := operations.GetIdentityRequest{ - IdentityID: identityID, - } - res, err := r.client.Identities.GetIdentity(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.Identity == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromGetResponse(res.Identity) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *IdentityResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data *IdentityResourceModel - merge(ctx, req, resp, &data) - if resp.Diagnostics.HasError() { - return - } - - identityParams := *data.ToUpdateSDKType() - identityID := data.ID.ValueString() - request := operations.UpdateIdentityRequest{ - IdentityParams: identityParams, - IdentityID: identityID, - } - res, err := r.client.Identities.UpdateIdentity(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - if res.Identity == nil { - resp.Diagnostics.AddError("unexpected response from API. No response body", debugResponse(res.RawResponse)) - return - } - data.RefreshFromUpdateResponse(res.Identity) - - // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *IdentityResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var data *IdentityResourceModel - var item types.Object - - resp.Diagnostics.Append(req.State.Get(ctx, &item)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - - if resp.Diagnostics.HasError() { - return - } - - identityID := data.ID.ValueString() - request := operations.DeleteIdentityRequest{ - IdentityID: identityID, - } - res, err := r.client.Identities.DeleteIdentity(ctx, request) - if err != nil { - resp.Diagnostics.AddError("failure to invoke API", err.Error()) - return - } - if res == nil { - resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) - return - } - if res.StatusCode != 200 { - resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) - return - } - -} - -func (r *IdentityResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} diff --git a/internal/provider/identity_resource_sdk.go b/internal/provider/identity_resource_sdk.go deleted file mode 100755 index 46b40fe..0000000 --- a/internal/provider/identity_resource_sdk.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "github.com/hashicorp/terraform-plugin-framework/types" - "time" -) - -func (r *IdentityResourceModel) ToCreateSDKType() *shared.IdentityParams { - abbeyAccount := r.AbbeyAccount.ValueString() - metadata := r.Metadata.ValueString() - source := r.Source.ValueString() - out := shared.IdentityParams{ - AbbeyAccount: abbeyAccount, - Metadata: metadata, - Source: source, - } - return &out -} - -func (r *IdentityResourceModel) ToGetSDKType() *shared.IdentityParams { - out := r.ToCreateSDKType() - return out -} - -func (r *IdentityResourceModel) ToUpdateSDKType() *shared.IdentityParams { - out := r.ToCreateSDKType() - return out -} - -func (r *IdentityResourceModel) ToDeleteSDKType() *shared.IdentityParams { - out := r.ToCreateSDKType() - return out -} - -func (r *IdentityResourceModel) RefreshFromGetResponse(resp *shared.Identity) { - r.AbbeyAccount = types.StringValue(resp.AbbeyAccount) - r.CreatedAt = types.StringValue(resp.CreatedAt.Format(time.RFC3339)) - r.ID = types.StringValue(resp.ID) - r.Metadata = types.StringValue(resp.Metadata) - r.Source = types.StringValue(resp.Source) - r.UpdatedAt = types.StringValue(resp.UpdatedAt.Format(time.RFC3339)) -} - -func (r *IdentityResourceModel) RefreshFromCreateResponse(resp *shared.Identity) { - r.RefreshFromGetResponse(resp) -} - -func (r *IdentityResourceModel) RefreshFromUpdateResponse(resp *shared.Identity) { - r.RefreshFromGetResponse(resp) -} diff --git a/internal/provider/provider.go b/internal/provider/provider.go old mode 100755 new mode 100644 index c9a79ee..f2f8df8 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1,106 +1,110 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - package provider import ( - "abbey/v2/internal/sdk" - "abbey/v2/internal/sdk/pkg/models/shared" "context" - + "github.com/go-provider-sdk/pkg/client" + "github.com/go-provider-sdk/pkg/clientconfig" "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/provider/schema" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" + + "abbey/v2/internal/provider/grantkit" + + "abbey/v2/internal/provider/identity" + + "abbey/v2/internal/provider/demo" ) -var _ provider.Provider = &AbbeyProvider{} +// Ensure Provider satisfies various provider interfaces. +var _ provider.Provider = &Provider{} -type AbbeyProvider struct { - // version is set to the provider version on release, "dev" when the - // provider is built and ran locally, and "test" when running acceptance - // testing. +type Provider struct { version string } -// AbbeyProviderModel describes the provider data model. -type AbbeyProviderModel struct { - ServerURL types.String `tfsdk:"server_url"` +type abbeyProviderModel struct { + ServerUrl types.String `tfsdk:"server_url"` BearerAuth types.String `tfsdk:"bearer_auth"` } -func (p *AbbeyProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { +func (p *Provider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { resp.TypeName = "abbey" - resp.Version = p.version + resp.Version = "0.2.7" } -func (p *AbbeyProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { +func (p *Provider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { resp.Schema = schema.Schema{ - MarkdownDescription: `Abbey API: The public Abbey API. Used for integrating with Abbey and building interfaces to extend the Abbey platform.` + "\n" + - `See https://docs.abbey.io for more information.` + "\n" + - ``, Attributes: map[string]schema.Attribute{ "server_url": schema.StringAttribute{ - MarkdownDescription: "Server URL (defaults to https://api.abbey.io/v1)", - Optional: true, - Required: false, + Required: true, + Sensitive: false, + Description: "The API host.", }, "bearer_auth": schema.StringAttribute{ - Optional: true, - Sensitive: true, + Required: true, + Sensitive: true, + Description: "The authentication token.", }, }, } } -func (p *AbbeyProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { - var data AbbeyProviderModel +func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { + var dataModel abbeyProviderModel - resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + resp.Diagnostics.Append(req.Config.Get(ctx, &dataModel)...) if resp.Diagnostics.HasError() { return } - ServerURL := data.ServerURL.ValueString() - - if ServerURL == "" { - ServerURL = "https://api.abbey.io/v1" + if dataModel.ServerUrl.IsUnknown() { + resp.Diagnostics.AddAttributeError( + path.Root("server_url"), + "Unknown ServerUrl", + "Cannot create API client without server_url.", + ) + return } - bearerAuth := data.BearerAuth.ValueString() - security := shared.Security{ - BearerAuth: bearerAuth, + if dataModel.BearerAuth.IsUnknown() { + resp.Diagnostics.AddAttributeError( + path.Root("bearer_auth"), + "Unknown BearerAuth", + "Cannot create API client without bearer_auth.", + ) + return } - opts := []sdk.SDKOption{ - sdk.WithServerURL(ServerURL), - sdk.WithSecurity(security), - } - client := sdk.New(opts...) + config := clientconfig.NewConfig() + config.SetBaseUrl(dataModel.ServerUrl.ValueString()) + config.SetAccessToken(dataModel.BearerAuth.ValueString()) + apiClient := client.NewClient(config) - resp.DataSourceData = client - resp.ResourceData = client + // Example of setting the client in resp + resp.DataSourceData = apiClient + resp.ResourceData = apiClient } -func (p *AbbeyProvider) Resources(ctx context.Context) []func() resource.Resource { - return []func() resource.Resource{ - NewDemoResource, - NewGrantKitResource, - NewIdentityResource, - } +func (p *Provider) Resources(ctx context.Context) []func() resource.Resource { + resources := []func() resource.Resource{} + resources = append(resources, grantkit.NewGrantKitResource) + resources = append(resources, identity.NewIdentityResource) + resources = append(resources, demo.NewDemoResource) + return resources } -func (p *AbbeyProvider) DataSources(ctx context.Context) []func() datasource.DataSource { - return []func() datasource.DataSource{ - NewGrantKitDataSource, - NewIdentityDataSource, - } +func (p *Provider) DataSources(ctx context.Context) []func() datasource.DataSource { + dataSources := []func() datasource.DataSource{} + return dataSources } func New(version string) func() provider.Provider { return func() provider.Provider { - return &AbbeyProvider{ + return &Provider{ version: version, } } diff --git a/internal/provider/reflect/diags.go b/internal/provider/reflect/diags.go deleted file mode 100755 index a91bba9..0000000 --- a/internal/provider/reflect/diags.go +++ /dev/null @@ -1,115 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "fmt" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -func toTerraform5ValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { - return diag.NewAttributeErrorDiagnostic( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) -} - -func toTerraformValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { - return diag.NewAttributeErrorDiagnostic( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert the Attribute value into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) -} - -func validateValueErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { - return diag.NewAttributeErrorDiagnostic( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to validate the Terraform value type. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) -} - -func valueFromTerraformErrorDiag(err error, path path.Path) diag.DiagnosticWithPath { - return diag.NewAttributeErrorDiagnostic( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert the Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) -} - -type DiagIntoIncompatibleType struct { - Val tftypes.Value - TargetType reflect.Type - Err error -} - -func (d DiagIntoIncompatibleType) Severity() diag.Severity { - return diag.SeverityError -} - -func (d DiagIntoIncompatibleType) Summary() string { - return "Value Conversion Error" -} - -func (d DiagIntoIncompatibleType) Detail() string { - return fmt.Sprintf("An unexpected error was encountered trying to convert %T into %s. This is always an error in the provider. Please report the following to the provider developer:\n\n%s", d.Val, d.TargetType, d.Err.Error()) -} - -func (d DiagIntoIncompatibleType) Equal(o diag.Diagnostic) bool { - od, ok := o.(DiagIntoIncompatibleType) - if !ok { - return false - } - if !d.Val.Equal(od.Val) { - return false - } - if d.TargetType != od.TargetType { - return false - } - if d.Err.Error() != od.Err.Error() { - return false - } - return true -} - -type DiagNewAttributeValueIntoWrongType struct { - ValType reflect.Type - TargetType reflect.Type - SchemaType attr.Type -} - -func (d DiagNewAttributeValueIntoWrongType) Severity() diag.Severity { - return diag.SeverityError -} - -func (d DiagNewAttributeValueIntoWrongType) Summary() string { - return "Value Conversion Error" -} - -func (d DiagNewAttributeValueIntoWrongType) Detail() string { - return fmt.Sprintf("An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\nCannot use attr.Value %s, only %s is supported because %T is the type in the schema", d.TargetType, d.ValType, d.SchemaType) -} - -func (d DiagNewAttributeValueIntoWrongType) Equal(o diag.Diagnostic) bool { - od, ok := o.(DiagNewAttributeValueIntoWrongType) - if !ok { - return false - } - if d.ValType != od.ValType { - return false - } - if d.TargetType != od.TargetType { - return false - } - if !d.SchemaType.Equal(od.SchemaType) { - return false - } - return true -} diff --git a/internal/provider/reflect/doc.go b/internal/provider/reflect/doc.go deleted file mode 100755 index ec91111..0000000 --- a/internal/provider/reflect/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -// Package reflect is a forked version of https://github.com/hashicorp/terraform-plugin-framework/tree/main/internal/reflect -// that has been modified to support speakeasy's terraform generator. -// In particular, behaviour differs in that it is intended to support merging Terraform State and Terraform Plan structures -// into a single data structure, with Known Plan values overriding State values. This allows for code to be written -// that drives API calls from a single point of truth. -// Fork Commit hash is 99f28445b60580b6e39afda88a4bb469461f9bbb -package reflect diff --git a/internal/provider/reflect/generic_attr_value.go b/internal/provider/reflect/generic_attr_value.go deleted file mode 100755 index 430ce2f..0000000 --- a/internal/provider/reflect/generic_attr_value.go +++ /dev/null @@ -1,14 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" -) - -func IsGenericAttrValue(ctx context.Context, target interface{}) bool { - return reflect.TypeOf((*attr.Value)(nil)) == reflect.TypeOf(target) -} diff --git a/internal/provider/reflect/helpers.go b/internal/provider/reflect/helpers.go deleted file mode 100755 index 82b9515..0000000 --- a/internal/provider/reflect/helpers.go +++ /dev/null @@ -1,98 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "reflect" - "regexp" - "strings" - - "github.com/hashicorp/terraform-plugin-framework/path" -) - -// trueReflectValue returns the reflect.Value for `in` after derefencing all -// the pointers and unwrapping all the interfaces. It's the concrete value -// beneath it all. -func trueReflectValue(val reflect.Value) reflect.Value { - kind := val.Type().Kind() - for kind == reflect.Interface || kind == reflect.Ptr { - innerVal := val.Elem() - if !innerVal.IsValid() { - break - } - val = innerVal - kind = val.Type().Kind() - } - return val -} - -// commaSeparatedString returns an English joining of the strings in `in`, -// using "and" and commas as appropriate. -func commaSeparatedString(in []string) string { - switch len(in) { - case 0: - return "" - case 1: - return in[0] - case 2: - return strings.Join(in, " and ") - default: - in[len(in)-1] = "and " + in[len(in)-1] - return strings.Join(in, ", ") - } -} - -// getStructTags returns a map of Terraform field names to their position in -// the tags of the struct `in`. `in` must be a struct. -func getStructTags(_ context.Context, in reflect.Value, path path.Path) (map[string]int, error) { - tags := map[string]int{} - typ := trueReflectValue(in).Type() - if typ.Kind() != reflect.Struct { - return nil, fmt.Errorf("%s: can't get struct tags of %s, is not a struct", path, in.Type()) - } - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - if field.PkgPath != "" { - // skip unexported fields - continue - } - tag := field.Tag.Get(`tfsdk`) - if tag == "-" { - // skip explicitly excluded fields - continue - } - if tag == "" { - return nil, fmt.Errorf(`%s: need a struct tag for "tfsdk" on %s`, path, field.Name) - } - path := path.AtName(tag) - if !isValidFieldName(tag) { - return nil, fmt.Errorf("%s: invalid field name, must only use lowercase letters, underscores, and numbers, and must start with a letter", path) - } - if other, ok := tags[tag]; ok { - return nil, fmt.Errorf("%s: can't use field name for both %s and %s", path, typ.Field(other).Name, field.Name) - } - tags[tag] = i - } - return tags, nil -} - -// isValidFieldName returns true if `name` can be used as a field name in a -// Terraform resource or data source. -func isValidFieldName(name string) bool { - re := regexp.MustCompile("^[a-z][a-z0-9_]*$") - return re.MatchString(name) -} - -// canBeNil returns true if `target`'s type can hold a nil value -func canBeNil(target reflect.Value) bool { - switch target.Kind() { - case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface: - // these types can all hold nils - return true - default: - // nothing else can be set to nil - return false - } -} diff --git a/internal/provider/reflect/interfaces.go b/internal/provider/reflect/interfaces.go deleted file mode 100755 index 364ff86..0000000 --- a/internal/provider/reflect/interfaces.go +++ /dev/null @@ -1,353 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// Unknownable is an interface for types that can be explicitly set to known or -// unknown. -type Unknownable interface { - SetUnknown(context.Context, bool) error - SetValue(context.Context, interface{}) error - GetUnknown(context.Context) bool - GetValue(context.Context) interface{} -} - -// NewUnknownable creates a zero value of `target` (or the concrete type it's -// referencing, if it's a pointer) and calls its SetUnknown method. -// -// It is meant to be called through Into, not directly. -func NewUnknownable(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - receiver := pointerSafeZeroValue(ctx, target) - method := receiver.MethodByName("SetUnknown") - if !method.IsValid() { - err := fmt.Errorf("cannot find SetUnknown method on type %s", receiver.Type().String()) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - results := method.Call([]reflect.Value{ - reflect.ValueOf(ctx), - reflect.ValueOf(!val.IsKnown()), - }) - err := results[0].Interface() - if err != nil { - var underlyingErr error - switch e := err.(type) { - case error: - underlyingErr = e - default: - underlyingErr = fmt.Errorf("unknown error type %T: %v", e, e) - } - underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), - ) - return target, diags - } - return receiver, diags -} - -// FromUnknownable creates an attr.Value from the data in an Unknownable. -// -// It is meant to be called through FromValue, not directly. -func FromUnknownable(ctx context.Context, typ attr.Type, val Unknownable, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - if val.GetUnknown(ctx) { - tfVal := tftypes.NewValue(typ.TerraformType(ctx), tftypes.UnknownValue) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - res, err := typ.ValueFromTerraform(ctx, tfVal) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - return res, nil - } - err := tftypes.ValidateValue(typ.TerraformType(ctx), val.GetValue(ctx)) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - - tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx)) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - res, err := typ.ValueFromTerraform(ctx, tfVal) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - return res, nil -} - -// Nullable is an interface for types that can be explicitly set to null. -type Nullable interface { - SetNull(context.Context, bool) error - SetValue(context.Context, interface{}) error - GetNull(context.Context) bool - GetValue(context.Context) interface{} -} - -// NewNullable creates a zero value of `target` (or the concrete type it's -// referencing, if it's a pointer) and calls its SetNull method. -// -// It is meant to be called through Into, not directly. -func NewNullable(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - receiver := pointerSafeZeroValue(ctx, target) - method := receiver.MethodByName("SetNull") - if !method.IsValid() { - err := fmt.Errorf("cannot find SetNull method on type %s", receiver.Type().String()) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - results := method.Call([]reflect.Value{ - reflect.ValueOf(ctx), - reflect.ValueOf(val.IsNull()), - }) - err := results[0].Interface() - if err != nil { - var underlyingErr error - switch e := err.(type) { - case error: - underlyingErr = e - default: - underlyingErr = fmt.Errorf("unknown error type: %T", e) - } - underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), - ) - return target, diags - } - return receiver, diags -} - -// FromNullable creates an attr.Value from the data in a Nullable. -// -// It is meant to be called through FromValue, not directly. -func FromNullable(ctx context.Context, typ attr.Type, val Nullable, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - if val.GetNull(ctx) { - tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - res, err := typ.ValueFromTerraform(ctx, tfVal) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - return res, nil - } - err := tftypes.ValidateValue(typ.TerraformType(ctx), val.GetValue(ctx)) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - - tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx)) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - res, err := typ.ValueFromTerraform(ctx, tfVal) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - return res, diags -} - -// NewValueConverter creates a zero value of `target` (or the concrete type -// it's referencing, if it's a pointer) and calls its FromTerraform5Value -// method. -// -// It is meant to be called through Into, not directly. -func NewValueConverter(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - receiver := pointerSafeZeroValue(ctx, target) - method := receiver.MethodByName("FromTerraform5Value") - if !method.IsValid() { - err := fmt.Errorf("could not find FromTerraform5Type method on type %s", receiver.Type().String()) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - results := method.Call([]reflect.Value{reflect.ValueOf(val)}) - err := results[0].Interface() - if err != nil { - var underlyingErr error - switch e := err.(type) { - case error: - underlyingErr = e - default: - underlyingErr = fmt.Errorf("unknown error type: %T", e) - } - underlyingErr = fmt.Errorf("reflection error: %w", underlyingErr) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert into a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+underlyingErr.Error(), - ) - return target, diags - } - return receiver, diags -} - -// FromValueCreator creates an attr.Value from the data in a -// tftypes.ValueCreator, calling its ToTerraform5Value method and converting -// the result to an attr.Value using `typ`. -// -// It is meant to be called from FromValue, not directly. -func FromValueCreator(ctx context.Context, typ attr.Type, val tftypes.ValueCreator, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - raw, err := val.ToTerraform5Value() - if err != nil { - return nil, append(diags, toTerraform5ValueErrorDiag(err, path)) - } - err = tftypes.ValidateValue(typ.TerraformType(ctx), raw) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfVal := tftypes.NewValue(typ.TerraformType(ctx), raw) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - res, err := typ.ValueFromTerraform(ctx, tfVal) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - return res, diags -} - -// NewAttributeValue creates a new reflect.Value by calling the -// ValueFromTerraform method on `typ`. It will return an error if the returned -// `attr.Value` is not the same type as `target`. -// -// It is meant to be called through Into, not directly. -func NewAttributeValue(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, val, path)...) - - if diags.HasError() { - return target, diags - } - } - - res, err := typ.ValueFromTerraform(ctx, val) - if err != nil { - return target, append(diags, valueFromTerraformErrorDiag(err, path)) - } - if reflect.TypeOf(res) != target.Type() { - diags.Append(diag.WithPath(path, DiagNewAttributeValueIntoWrongType{ - ValType: reflect.TypeOf(res), - TargetType: target.Type(), - SchemaType: typ, - })) - return target, diags - } - return reflect.ValueOf(res), diags -} - -// FromAttributeValue creates an attr.Value from an attr.Value. It just returns -// the attr.Value it is passed or an error if there is an unexpected mismatch -// between the attr.Type and attr.Value. -// -// It is meant to be called through FromValue, not directly. -func FromAttributeValue(ctx context.Context, typ attr.Type, val attr.Value, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - // Since the reflection logic is a generic Go type implementation with - // user input, it is possible to get into awkward situations where - // the logic is expecting a certain type while a value may not be - // compatible. This check will ensure the framework raises its own - // error is there is a mismatch, rather than a terraform-plugin-go - // error or worse a panic. - // - // If this validation causes major issues, another option is to - // validate via tftypes.Type for both the type and value type. - if !typ.Equal(val.Type(ctx)) { - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered while verifying an attribute value matched its expected type to prevent unexpected behavior or panics. "+ - "This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - fmt.Sprintf("Expected type: %s\n", typ)+ - fmt.Sprintf("Value type: %s\n", val.Type(ctx))+ - fmt.Sprintf("Path: %s", path), - ) - - return nil, diags - } - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - tfVal, err := val.ToTerraformValue(ctx) - if err != nil { - return val, append(diags, toTerraformValueErrorDiag(err, path)) - } - - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return val, diags - } - } - - return val, diags -} diff --git a/internal/provider/reflect/into.go b/internal/provider/reflect/into.go deleted file mode 100755 index c53d1be..0000000 --- a/internal/provider/reflect/into.go +++ /dev/null @@ -1,216 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "math/big" - "reflect" - - "github.com/hashicorp/terraform-plugin-go/tftypes" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" -) - -// Into uses the data in `val` to populate `target`, using the reflection -// package to recursively reflect into structs and slices. If `target` is an -// attr.Value, its assignment method will be used instead of reflecting. If -// `target` is a tftypes.ValueConverter, the FromTerraformValue method will be -// used instead of using reflection. Primitives are set using the val.As -// method. Structs use reflection: each exported struct field must have a -// "tfsdk" tag with the name of the field in the tftypes.Value, and all fields -// in the tftypes.Value must have a corresponding property in the struct. Into -// will be called for each struct field. Slices will have Into called for each -// element. -func Into(ctx context.Context, typ attr.Type, val tftypes.Value, target interface{}, opts Options, path path.Path) diag.Diagnostics { - var diags diag.Diagnostics - - v := reflect.ValueOf(target) - if v.Kind() != reflect.Ptr { - err := fmt.Errorf("target must be a pointer, got %T, which is a %s", target, v.Kind()) - diags.AddAttributeError( - path, - "Value Conversion Error", - fmt.Sprintf("An unexpected error was encountered trying to convert the value. This is always an error in the provider. Please report the following to the provider developer:\n\nPath: %s\nError: %s", path.String(), err.Error()), - ) - return diags - } - result, diags := BuildValue(ctx, typ, val, v.Elem(), opts, path) - if diags.HasError() { - return diags - } - v.Elem().Set(result) - return diags -} - -// BuildValue constructs a reflect.Value of the same type as `target`, -// populated with the data in `val`. It will defensively instantiate new values -// to set, making it safe for use with pointer types which may be nil. It tries -// to give consumers the ability to override its default behaviors wherever -// possible. -func BuildValue(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - // if this isn't a valid reflect.Value, bail before we accidentally - // panic - if !target.IsValid() { - err := fmt.Errorf("invalid target") - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - - // ------------------------- - // -- Fork Start ----------- - // ------------------------- - - if !val.IsKnown() { - return target, diags - } - - // ------------------------- - // -- Fork End - ----------- - // ------------------------- - - // if this is an attr.Value, build the type from that - if target.Type().Implements(reflect.TypeOf((*attr.Value)(nil)).Elem()) { - return NewAttributeValue(ctx, typ, val, target, opts, path) - } - // if this tells tftypes how to build an instance of it out of a - // tftypes.Value, well, that's what we want, so do that instead of our - // default logic. - if target.Type().Implements(reflect.TypeOf((*tftypes.ValueConverter)(nil)).Elem()) { - return NewValueConverter(ctx, typ, val, target, opts, path) - } - // if this can explicitly be set to unknown, do that - if target.Type().Implements(reflect.TypeOf((*Unknownable)(nil)).Elem()) { - res, unknownableDiags := NewUnknownable(ctx, typ, val, target, opts, path) - diags.Append(unknownableDiags...) - if diags.HasError() { - return target, diags - } - target = res - // only return if it's unknown; we want to call SetUnknown - // either way, but if the value is unknown, there's nothing - // else to do, so bail - if !val.IsKnown() { - return target, nil - } - } - // if this can explicitly be set to null, do that - if target.Type().Implements(reflect.TypeOf((*Nullable)(nil)).Elem()) { - res, nullableDiags := NewNullable(ctx, typ, val, target, opts, path) - diags.Append(nullableDiags...) - if diags.HasError() { - return target, diags - } - target = res - // only return if it's null; we want to call SetNull either - // way, but if the value is null, there's nothing else to do, - // so bail - if val.IsNull() { - return target, nil - } - } - // ------------------------- - // -- Fork Start ----------- - // ------------------------- - //if !val.IsKnown() { - // // we already handled unknown the only ways we can - // // we checked that target doesn't have a SetUnknown method we - // // can call - // // we checked that target isn't an attr.Value - // // all that's left to us now is to set it as an empty value or - // // throw an error, depending on what's in opts - // if !opts.UnhandledUnknownAsEmpty { - // diags.AddAttributeError( - // path, - // "Value Conversion Error", - // "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - // "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - // fmt.Sprintf("Path: %s\nTarget Type: %s\nSuggested Type: %s", path.String(), target.Type(), reflect.TypeOf(typ.ValueType(ctx))), - // ) - // return target, diags - // } - // // we want to set unhandled unknowns to the empty value - // return reflect.Zero(target.Type()), diags - //} - // ------------------------- - // -- Fork End - ----------- - // ------------------------- - - if val.IsNull() { - // we already handled null the only ways we can - // we checked that target doesn't have a SetNull method we can - // call - // we checked that target isn't an attr.Value - // all that's left to us now is to set it as an empty value or - // throw an error, depending on what's in opts - if canBeNil(target) || opts.UnhandledNullAsEmpty { - return reflect.Zero(target.Type()), nil - } - - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - fmt.Sprintf("Path: %s\nTarget Type: %s\nSuggested `types` Type: %s\nSuggested Pointer Type: *%s", path.String(), target.Type(), reflect.TypeOf(typ.ValueType(ctx)), target.Type()), - ) - - return target, diags - } - // *big.Float and *big.Int are technically pointers, but we want them - // handled as numbers - if target.Type() == reflect.TypeOf(big.NewFloat(0)) || target.Type() == reflect.TypeOf(big.NewInt(0)) { - return Number(ctx, typ, val, target, opts, path) - } - switch target.Kind() { - case reflect.Struct: - val, valDiags := Struct(ctx, typ, val, target, opts, path) - diags.Append(valDiags...) - return val, diags - case reflect.Bool, reflect.String: - val, valDiags := Primitive(ctx, typ, val, target, path) - diags.Append(valDiags...) - return val, diags - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, - reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: - // numbers are the wooooorst and need their own special handling - // because we can't just hand them off to tftypes and also - // because we can't just make people use *big.Floats, because a - // nil *big.Float will crash everything if we don't handle it - // as a special case, so let's just special case numbers and - // let people use the types they want - val, valDiags := Number(ctx, typ, val, target, opts, path) - diags.Append(valDiags...) - return val, diags - case reflect.Slice: - val, valDiags := reflectSlice(ctx, typ, val, target, opts, path) - diags.Append(valDiags...) - return val, diags - case reflect.Map: - val, valDiags := Map(ctx, typ, val, target, opts, path) - diags.Append(valDiags...) - return val, diags - case reflect.Ptr: - val, valDiags := Pointer(ctx, typ, val, target, opts, path) - diags.Append(valDiags...) - return val, diags - default: - err := fmt.Errorf("don't know how to reflect %s into %s", val.Type(), target.Type()) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } -} diff --git a/internal/provider/reflect/map.go b/internal/provider/reflect/map.go deleted file mode 100755 index 3310d42..0000000 --- a/internal/provider/reflect/map.go +++ /dev/null @@ -1,188 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// Map creates a map value that matches the type of `target`, and populates it -// with the contents of `val`. -func Map(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - underlyingValue := trueReflectValue(target) - - // this only works with maps, so check that out first - if underlyingValue.Kind() != reflect.Map { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: fmt.Errorf("expected a map type, got %s", target.Type()), - })) - return target, diags - } - if !val.Type().Is(tftypes.Map{}) { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: fmt.Errorf("cannot reflect %s into a map, must be a map", val.Type().String()), - })) - return target, diags - } - elemTyper, ok := typ.(attr.TypeWithElementType) - if !ok { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: fmt.Errorf("cannot reflect map using type information provided by %T, %T must be an attr.TypeWithElementType", typ, typ), - })) - return target, diags - } - - // we need our value to become a map of values so we can iterate over - // them and handle them individually - values := map[string]tftypes.Value{} - err := val.As(&values) - if err != nil { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: err, - })) - return target, diags - } - - // we need to know the type the slice is wrapping - elemType := underlyingValue.Type().Elem() - elemAttrType := elemTyper.ElementType() - - // we want an empty version of the map - m := reflect.MakeMapWithSize(underlyingValue.Type(), len(values)) - - // go over each of the values passed in, create a Go value of the right - // type for them, and add it to our new map - for key, value := range values { - // create a new Go value of the type that can go in the map - targetValue := reflect.Zero(elemType) - - // update our path so we can have nice errors - path := path.AtMapKey(key) - - // reflect the value into our new target - result, elemDiags := BuildValue(ctx, elemAttrType, value, targetValue, opts, path) - diags.Append(elemDiags...) - - if diags.HasError() { - return target, diags - } - - m.SetMapIndex(reflect.ValueOf(key), result) - } - - return m, diags -} - -// FromMap returns an attr.Value representing the data contained in `val`. -// `val` must be a map type with keys that are a string type. The attr.Value -// will be of the type produced by `typ`. -// -// It is meant to be called through FromValue, not directly. -func FromMap(ctx context.Context, typ attr.TypeWithElementType, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - tfType := typ.TerraformType(ctx) - - if val.IsNil() { - tfVal := tftypes.NewValue(tfType, nil) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - attrVal, err := typ.ValueFromTerraform(ctx, tfVal) - - if err != nil { - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from map value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - - return attrVal, diags - } - - elemType := typ.ElementType() - tfElems := map[string]tftypes.Value{} - for _, key := range val.MapKeys() { - if key.Kind() != reflect.String { - err := fmt.Errorf("map keys must be strings, got %s", key.Type()) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert into a Terraform value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - val, valDiags := FromValue(ctx, elemType, val.MapIndex(key).Interface(), path.AtMapKey(key.String())) - diags.Append(valDiags...) - - if diags.HasError() { - return nil, diags - } - tfVal, err := val.ToTerraformValue(ctx) - if err != nil { - return nil, append(diags, toTerraformValueErrorDiag(err, path)) - } - - if typeWithValidate, ok := elemType.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path.AtMapKey(key.String()))...) - - if diags.HasError() { - return nil, diags - } - } - - tfElems[key.String()] = tfVal - } - - err := tftypes.ValidateValue(tfType, tfElems) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - - tfVal := tftypes.NewValue(tfType, tfElems) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - attrVal, err := typ.ValueFromTerraform(ctx, tfVal) - - if err != nil { - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to map value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - - return attrVal, diags -} diff --git a/internal/provider/reflect/number.go b/internal/provider/reflect/number.go deleted file mode 100755 index a0e4126..0000000 --- a/internal/provider/reflect/number.go +++ /dev/null @@ -1,374 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "math" - "math/big" - "reflect" - "strconv" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// Number creates a *big.Float and populates it with the data in `val`. It then -// gets converted to the type of `target`, as long as `target` is a valid -// number type (any of the built-in int, uint, or float types, *big.Float, and -// *big.Int). -// -// Number will loudly fail when a number cannot be losslessly represented using -// the requested type, unless opts.AllowRoundingNumbers is set to true. This -// setting is mildly dangerous, because Terraform does not like when you round -// things, as a general rule of thumb. -// -// It is meant to be called through Into, not directly. -func Number(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - result := big.NewFloat(0) - err := val.As(&result) - if err != nil { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Err: err, - TargetType: target.Type(), - Val: val, - })) - return target, diags - } - roundingError := fmt.Errorf("cannot store %s in %s", result.String(), target.Type()) - roundingErrorDiag := diag.NewAttributeErrorDiagnostic( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+roundingError.Error(), - ) - - switch target.Type() { - case reflect.TypeOf(big.NewFloat(0)): - return reflect.ValueOf(result), diags - case reflect.TypeOf(big.NewInt(0)): - intResult, acc := result.Int(nil) - if acc != big.Exact && !opts.AllowRoundingNumbers { - return reflect.ValueOf(result), append(diags, roundingErrorDiag) - } - return reflect.ValueOf(intResult), diags - } - switch target.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64: - intResult, acc := result.Int64() - if acc != big.Exact && !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - switch target.Kind() { - case reflect.Int: - if strconv.IntSize == 32 && intResult > math.MaxInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt32 - } - if strconv.IntSize == 32 && intResult < math.MinInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt32 - } - return reflect.ValueOf(int(intResult)), diags - case reflect.Int8: - if intResult > math.MaxInt8 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt8 - } - if intResult < math.MinInt8 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt8 - } - return reflect.ValueOf(int8(intResult)), diags - case reflect.Int16: - if intResult > math.MaxInt16 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt16 - } - if intResult < math.MinInt16 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt16 - } - return reflect.ValueOf(int16(intResult)), diags - case reflect.Int32: - if intResult > math.MaxInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt32 - } - if intResult < math.MinInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt32 - } - return reflect.ValueOf(int32(intResult)), diags - case reflect.Int64: - return reflect.ValueOf(intResult), diags - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64: - uintResult, acc := result.Uint64() - if acc != big.Exact && !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - switch target.Kind() { - case reflect.Uint: - if strconv.IntSize == 32 && uintResult > math.MaxUint32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint32 - } - return reflect.ValueOf(uint(uintResult)), diags - case reflect.Uint8: - if uintResult > math.MaxUint8 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint8 - } - return reflect.ValueOf(uint8(uintResult)), diags - case reflect.Uint16: - if uintResult > math.MaxUint16 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint16 - } - return reflect.ValueOf(uint16(uintResult)), diags - case reflect.Uint32: - if uintResult > math.MaxUint32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint32 - } - return reflect.ValueOf(uint32(uintResult)), diags - case reflect.Uint64: - return reflect.ValueOf(uintResult), diags - } - case reflect.Float32: - floatResult, acc := result.Float32() - if acc != big.Exact && !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } else if acc == big.Above { - floatResult = math.MaxFloat32 - } else if acc == big.Below { - floatResult = math.SmallestNonzeroFloat32 - } else if acc != big.Exact { - err := fmt.Errorf("unsure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - return reflect.ValueOf(floatResult), diags - case reflect.Float64: - floatResult, acc := result.Float64() - if acc != big.Exact && !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - if acc == big.Above { - if floatResult == math.Inf(1) || floatResult == math.MaxFloat64 { - floatResult = math.MaxFloat64 - } else if floatResult == 0.0 || floatResult == math.SmallestNonzeroFloat64 { - floatResult = -math.SmallestNonzeroFloat64 - } else { - err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - } else if acc == big.Below { - if floatResult == math.Inf(-1) || floatResult == -math.MaxFloat64 { - floatResult = -math.MaxFloat64 - } else if floatResult == -0.0 || floatResult == -math.SmallestNonzeroFloat64 { //nolint:staticcheck - floatResult = math.SmallestNonzeroFloat64 - } else { - err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - } else if acc != big.Exact { - err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - return reflect.ValueOf(floatResult), diags - } - err = fmt.Errorf("cannot convert number to %s", target.Type()) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags -} - -// FromInt creates an attr.Value using `typ` from an int64. -// -// It is meant to be called through FromValue, not directly. -func FromInt(ctx context.Context, typ attr.Type, val int64, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - err := tftypes.ValidateValue(tftypes.Number, val) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfNum := tftypes.NewValue(tftypes.Number, val) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) - - if diags.HasError() { - return nil, diags - } - } - - num, err := typ.ValueFromTerraform(ctx, tfNum) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return num, diags -} - -// FromUint creates an attr.Value using `typ` from a uint64. -// -// It is meant to be called through FromValue, not directly. -func FromUint(ctx context.Context, typ attr.Type, val uint64, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - err := tftypes.ValidateValue(tftypes.Number, val) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfNum := tftypes.NewValue(tftypes.Number, val) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) - - if diags.HasError() { - return nil, diags - } - } - - num, err := typ.ValueFromTerraform(ctx, tfNum) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return num, diags -} - -// FromFloat creates an attr.Value using `typ` from a float64. -// -// It is meant to be called through FromValue, not directly. -func FromFloat(ctx context.Context, typ attr.Type, val float64, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - err := tftypes.ValidateValue(tftypes.Number, val) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfNum := tftypes.NewValue(tftypes.Number, val) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) - - if diags.HasError() { - return nil, diags - } - } - - num, err := typ.ValueFromTerraform(ctx, tfNum) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return num, diags -} - -// FromBigFloat creates an attr.Value using `typ` from a *big.Float. -// -// It is meant to be called through FromValue, not directly. -func FromBigFloat(ctx context.Context, typ attr.Type, val *big.Float, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - err := tftypes.ValidateValue(tftypes.Number, val) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfNum := tftypes.NewValue(tftypes.Number, val) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) - - if diags.HasError() { - return nil, diags - } - } - - num, err := typ.ValueFromTerraform(ctx, tfNum) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return num, diags -} - -// FromBigInt creates an attr.Value using `typ` from a *big.Int. -// -// It is meant to be called through FromValue, not directly. -func FromBigInt(ctx context.Context, typ attr.Type, val *big.Int, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - fl := big.NewFloat(0).SetInt(val) - err := tftypes.ValidateValue(tftypes.Number, fl) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfNum := tftypes.NewValue(tftypes.Number, fl) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...) - - if diags.HasError() { - return nil, diags - } - } - - num, err := typ.ValueFromTerraform(ctx, tfNum) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return num, diags -} diff --git a/internal/provider/reflect/options.go b/internal/provider/reflect/options.go deleted file mode 100755 index 490c5f1..0000000 --- a/internal/provider/reflect/options.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -// Options provides configuration settings for how the reflection behavior -// works, letting callers tweak different behaviors based on their needs. -type Options struct { - // UnhandledNullAsEmpty controls whether null values should be - // translated into empty values without provider interaction, or if - // they must be explicitly handled. - UnhandledNullAsEmpty bool - - // UnhandledUnknownAsEmpty controls whether null values should be - // translated into empty values without provider interaction, or if - // they must be explicitly handled. - UnhandledUnknownAsEmpty bool - - // AllowRoundingNumbers silently rounds numbers that don't fit - // perfectly in the types they're being stored in, rather than - // returning errors. Numbers will always be rounded towards 0. - AllowRoundingNumbers bool -} diff --git a/internal/provider/reflect/outof.go b/internal/provider/reflect/outof.go deleted file mode 100755 index 7852781..0000000 --- a/internal/provider/reflect/outof.go +++ /dev/null @@ -1,94 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "math/big" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// FromValue is the inverse of Into, taking a Go value (`val`) and transforming it -// into an attr.Value using the attr.Type supplied. `val` will first be -// transformed into a tftypes.Value, then passed to `typ`'s ValueFromTerraform -// method. -func FromValue(ctx context.Context, typ attr.Type, val interface{}, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - if v, ok := val.(attr.Value); ok { - return FromAttributeValue(ctx, typ, v, path) - } - if v, ok := val.(tftypes.ValueCreator); ok { - return FromValueCreator(ctx, typ, v, path) - } - if v, ok := val.(Unknownable); ok { - return FromUnknownable(ctx, typ, v, path) - } - if v, ok := val.(Nullable); ok { - return FromNullable(ctx, typ, v, path) - } - if bf, ok := val.(*big.Float); ok { - return FromBigFloat(ctx, typ, bf, path) - } - if bi, ok := val.(*big.Int); ok { - return FromBigInt(ctx, typ, bi, path) - } - value := reflect.ValueOf(val) - kind := value.Kind() - switch kind { - case reflect.Struct: - t, ok := typ.(attr.TypeWithAttributeTypes) - if !ok { - err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithAttributeTypes to hold %T", val, typ, typ, val) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - return FromStruct(ctx, t, value, path) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64: - return FromInt(ctx, typ, value.Int(), path) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64: - return FromUint(ctx, typ, value.Uint(), path) - case reflect.Float32, reflect.Float64: - return FromFloat(ctx, typ, value.Float(), path) - case reflect.Bool: - return FromBool(ctx, typ, value.Bool(), path) - case reflect.String: - return FromString(ctx, typ, value.String(), path) - case reflect.Slice: - return FromSlice(ctx, typ, value, path) - case reflect.Map: - t, ok := typ.(attr.TypeWithElementType) - if !ok { - err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithElementType to hold %T", val, typ, typ, val) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - return FromMap(ctx, t, value, path) - case reflect.Ptr: - return FromPointer(ctx, typ, value, path) - default: - err := fmt.Errorf("cannot construct attr.Type from %T (%s)", val, kind) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } -} diff --git a/internal/provider/reflect/pointer.go b/internal/provider/reflect/pointer.go deleted file mode 100755 index e02c9eb..0000000 --- a/internal/provider/reflect/pointer.go +++ /dev/null @@ -1,126 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// Pointer builds a new zero value of the concrete type that `target` -// references, populates it with BuildValue, and takes a pointer to it. -// -// It is meant to be called through Into, not directly. -func Pointer(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - if target.Kind() != reflect.Ptr { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: fmt.Errorf("cannot dereference pointer, not a pointer, is a %s (%s)", target.Type(), target.Kind()), - })) - return target, diags - } - // we may have gotten a nil pointer, so we need to create our own that - // we can set - // FORK START - pointer := target - if target.IsNil() { - pointer = reflect.New(target.Type().Elem()) - } - // FORK END - // build out whatever the pointer is pointing to - pointed, pointedDiags := BuildValue(ctx, typ, val, pointer.Elem(), opts, path) - diags.Append(pointedDiags...) - - if diags.HasError() { - return target, diags - } - // to be able to set the pointer to our new pointer, we need to create - // a pointer to the pointer - pointerPointer := reflect.New(pointer.Type()) - // we set the pointer we created on the pointer to the pointer - pointerPointer.Elem().Set(pointer) - // then it's settable, so we can now set the concrete value we created - // on the pointer - pointerPointer.Elem().Elem().Set(pointed) - // return the pointer we created - return pointerPointer.Elem(), diags -} - -// create a zero value of concrete type underlying any number of pointers, then -// wrap it in that number of pointers again. The end result is to wind up with -// the same exact type, except now you can be sure it's pointing to actual data -// and will not give you a nil pointer dereference panic unexpectedly. -func pointerSafeZeroValue(_ context.Context, target reflect.Value) reflect.Value { - pointer := target.Type() - var pointers int - for pointer.Kind() == reflect.Ptr { - pointer = pointer.Elem() - pointers++ - } - receiver := reflect.Zero(pointer) - for i := 0; i < pointers; i++ { - newReceiver := reflect.New(receiver.Type()) - newReceiver.Elem().Set(receiver) - receiver = newReceiver - } - return receiver -} - -// FromPointer turns a pointer into an attr.Value using `typ`. If the pointer -// is nil, the attr.Value will use its null representation. If it is not nil, -// it will recurse into FromValue to find the attr.Value of the type the value -// the pointer is referencing. -// -// It is meant to be called through FromValue, not directly. -func FromPointer(ctx context.Context, typ attr.Type, value reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - if value.Kind() != reflect.Ptr { - err := fmt.Errorf("cannot use type %s as a pointer", value.Type()) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from pointer value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - if value.IsNil() { - tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - attrVal, err := typ.ValueFromTerraform(ctx, tfVal) - - if err != nil { - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from pointer value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - - return attrVal, diags - } - - attrVal, attrValDiags := FromValue(ctx, typ, value.Elem().Interface(), path) - diags.Append(attrValDiags...) - - return attrVal, diags -} diff --git a/internal/provider/reflect/primitive.go b/internal/provider/reflect/primitive.go deleted file mode 100755 index 3113c39..0000000 --- a/internal/provider/reflect/primitive.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "errors" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// Primitive builds a string or boolean, depending on the type of `target`, and -// populates it with the data in `val`. -// -// It is meant to be called through `Into`, not directly. -func Primitive(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - switch target.Kind() { - case reflect.Bool: - var b bool - err := val.As(&b) - if err != nil { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: err, - })) - return target, diags - } - return reflect.ValueOf(b).Convert(target.Type()), nil - case reflect.String: - var s string - err := val.As(&s) - if err != nil { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: err, - })) - return target, diags - } - return reflect.ValueOf(s).Convert(target.Type()), nil - default: - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: errors.New("unknown type"), - })) - return target, diags - } -} - -// FromString returns an attr.Value as produced by `typ` from a string. -// -// It is meant to be called through FromValue, not directly. -func FromString(ctx context.Context, typ attr.Type, val string, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - err := tftypes.ValidateValue(tftypes.String, val) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfStr := tftypes.NewValue(tftypes.String, val) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfStr, path)...) - - if diags.HasError() { - return nil, diags - } - } - - str, err := typ.ValueFromTerraform(ctx, tfStr) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return str, diags -} - -// FromBool returns an attr.Value as produced by `typ` from a bool. -// -// It is meant to be called through FromValue, not directly. -func FromBool(ctx context.Context, typ attr.Type, val bool, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - err := tftypes.ValidateValue(tftypes.Bool, val) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - tfBool := tftypes.NewValue(tftypes.Bool, val) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfBool, path)...) - - if diags.HasError() { - return nil, diags - } - } - - b, err := typ.ValueFromTerraform(ctx, tfBool) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return b, diags -} diff --git a/internal/provider/reflect/slice.go b/internal/provider/reflect/slice.go deleted file mode 100755 index b91f729..0000000 --- a/internal/provider/reflect/slice.go +++ /dev/null @@ -1,214 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "reflect" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// build a slice of elements, matching the type of `target`, and fill it with -// the data in `val`. -func reflectSlice(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - // this only works with slices, so check that out first - if target.Kind() != reflect.Slice { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: fmt.Errorf("expected a slice type, got %s", target.Type()), - })) - return target, diags - } - // TODO: check that the val is a list or set or tuple - elemTyper, ok := typ.(attr.TypeWithElementType) - if !ok { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: fmt.Errorf("cannot reflect %s using type information provided by %T, %T must be an attr.TypeWithElementType", val.Type(), typ, typ), - })) - return target, diags - } - - // we need our value to become a list of values so we can iterate over - // them and handle them individually - var values []tftypes.Value - err := val.As(&values) - if err != nil { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: val, - TargetType: target.Type(), - Err: err, - })) - return target, diags - } - - // we need to know the type the slice is wrapping - elemType := target.Type().Elem() - elemAttrType := elemTyper.ElementType() - - // we want an empty version of the slice - slice := reflect.MakeSlice(target.Type(), 0, len(values)) - - // go over each of the values passed in, create a Go value of the right - // type for them, and add it to our new slice - for pos, value := range values { - // create a new Go value of the type that can go in the slice - targetValue := reflect.Zero(elemType) - - // update our path so we can have nice errors - valPath := path.AtListIndex(pos) - - if typ.TerraformType(ctx).Is(tftypes.Set{}) { - attrVal, err := elemAttrType.ValueFromTerraform(ctx, value) - - if err != nil { - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - - valPath = path.AtSetValue(attrVal) - } - - // reflect the value into our new target - val, valDiags := BuildValue(ctx, elemAttrType, value, targetValue, opts, valPath) - diags.Append(valDiags...) - - if diags.HasError() { - return target, diags - } - - // add the new target to our slice - slice = reflect.Append(slice, val) - } - - return slice, diags -} - -// FromSlice returns an attr.Value as produced by `typ` using the data in -// `val`. `val` must be a slice. `typ` must be an attr.TypeWithElementType or -// attr.TypeWithElementTypes. If the slice is nil, the representation of null -// for `typ` will be returned. Otherwise, FromSlice will recurse into FromValue -// for each element in the slice, using the element type or types defined on -// `typ` to construct values for them. -// -// It is meant to be called through FromValue, not directly. -func FromSlice(ctx context.Context, typ attr.Type, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - // TODO: support tuples, which are attr.TypeWithElementTypes - tfType := typ.TerraformType(ctx) - - if val.IsNil() { - tfVal := tftypes.NewValue(tfType, nil) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - attrVal, err := typ.ValueFromTerraform(ctx, tfVal) - - if err != nil { - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - - return attrVal, diags - } - - t, ok := typ.(attr.TypeWithElementType) - if !ok { - err := fmt.Errorf("cannot use type %T as schema type %T; %T must be an attr.TypeWithElementType to hold %T", val, typ, typ, val) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - - elemType := t.ElementType() - tfElems := make([]tftypes.Value, 0, val.Len()) - for i := 0; i < val.Len(); i++ { - // The underlying reflect.Slice is fetched by Index(). For set types, - // the path is value-based instead of index-based. Since there is only - // the index until the value is retrieved, this will pass the - // technically incorrect index-based path at first for framework - // debugging purposes, then correct the path afterwards. - valPath := path.AtListIndex(i) - - val, valDiags := FromValue(ctx, elemType, val.Index(i).Interface(), valPath) - diags.Append(valDiags...) - - if diags.HasError() { - return nil, diags - } - - tfVal, err := val.ToTerraformValue(ctx) - if err != nil { - return nil, append(diags, toTerraformValueErrorDiag(err, path)) - } - - if tfType.Is(tftypes.Set{}) { - valPath = path.AtSetValue(val) - } - - if typeWithValidate, ok := elemType.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, valPath)...) - if diags.HasError() { - return nil, diags - } - } - - tfElems = append(tfElems, tfVal) - } - - err := tftypes.ValidateValue(tfType, tfElems) - if err != nil { - return nil, append(diags, validateValueErrorDiag(err, path)) - } - - tfVal := tftypes.NewValue(tfType, tfElems) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - attrVal, err := typ.ValueFromTerraform(ctx, tfVal) - - if err != nil { - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from slice value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - - return attrVal, diags -} diff --git a/internal/provider/reflect/struct.go b/internal/provider/reflect/struct.go deleted file mode 100755 index b670228..0000000 --- a/internal/provider/reflect/struct.go +++ /dev/null @@ -1,266 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package reflect - -import ( - "context" - "fmt" - "reflect" - "strings" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -// Struct builds a new struct using the data in `object`, as long as `object` -// is a `tftypes.Object`. It will take the struct type from `target`, which -// must be a struct type. -// -// The properties on `target` must be tagged with a "tfsdk" label containing -// the field name to map to that property. Every property must be tagged, and -// every property must be present in the type of `object`, and all the -// attributes in the type of `object` must have a corresponding property. -// Properties that don't map to object attributes must have a `tfsdk:"-"` tag, -// explicitly defining them as not part of the object. This is to catch typos -// and other mistakes early. -// -// Struct is meant to be called from Into, not directly. -func Struct(ctx context.Context, typ attr.Type, object tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { - var diags diag.Diagnostics - - // this only works with object values, so make sure that constraint is - // met - if target.Kind() != reflect.Struct { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: object, - TargetType: target.Type(), - Err: fmt.Errorf("expected a struct type, got %s", target.Type()), - })) - return target, diags - } - if !object.Type().Is(tftypes.Object{}) { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: object, - TargetType: target.Type(), - Err: fmt.Errorf("cannot reflect %s into a struct, must be an object", object.Type().String()), - })) - return target, diags - } - attrsType, ok := typ.(attr.TypeWithAttributeTypes) - if !ok { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: object, - TargetType: target.Type(), - Err: fmt.Errorf("cannot reflect object using type information provided by %T, %T must be an attr.TypeWithAttributeTypes", typ, typ), - })) - return target, diags - } - - // collect a map of fields that are in the object passed in - var objectFields map[string]tftypes.Value - err := object.As(&objectFields) - if err != nil { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: object, - TargetType: target.Type(), - Err: err, - })) - return target, diags - } - - // collect a map of fields that are defined in the tags of the struct - // passed in - targetFields, err := getStructTags(ctx, target, path) - if err != nil { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: object, - TargetType: target.Type(), - Err: fmt.Errorf("error retrieving field names from struct tags: %w", err), - })) - return target, diags - } - - // we require an exact, 1:1 match of these fields to avoid typos - // leading to surprises, so let's ensure they have the exact same - // fields defined - var objectMissing, targetMissing []string - for field := range targetFields { - if _, ok := objectFields[field]; !ok { - objectMissing = append(objectMissing, field) - } - } - for field := range objectFields { - if _, ok := targetFields[field]; !ok { - targetMissing = append(targetMissing, field) - } - } - if len(objectMissing) > 0 || len(targetMissing) > 0 { - var missing []string - if len(objectMissing) > 0 { - missing = append(missing, fmt.Sprintf("Struct defines fields not found in object: %s.", commaSeparatedString(objectMissing))) - } - if len(targetMissing) > 0 { - missing = append(missing, fmt.Sprintf("Object defines fields not found in struct: %s.", commaSeparatedString(targetMissing))) - } - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: object, - TargetType: target.Type(), - Err: fmt.Errorf("mismatch between struct and object: %s", strings.Join(missing, " ")), - })) - return target, diags - } - - attrTypes := attrsType.AttributeTypes() - - // now that we know they match perfectly, fill the struct with the - // values in the object - // Fork start - //result := reflect.New(target.Type()).Elem() - var result reflect.Value - if target.CanSet() { - result = target - } else { - result = reflect.New(target.Type()).Elem() - } - // Fork End - for field, structFieldPos := range targetFields { - attrType, ok := attrTypes[field] - if !ok { - diags.Append(diag.WithPath(path, DiagIntoIncompatibleType{ - Val: object, - TargetType: target.Type(), - Err: fmt.Errorf("could not find type information for attribute in supplied attr.Type %T", typ), - })) - return target, diags - } - structField := result.Field(structFieldPos) - fieldVal, fieldValDiags := BuildValue(ctx, attrType, objectFields[field], structField, opts, path.AtName(field)) - diags.Append(fieldValDiags...) - - if diags.HasError() { - return target, diags - } - structField.Set(fieldVal) - } - return result, diags -} - -// FromStruct builds an attr.Value as produced by `typ` from the data in `val`. -// `val` must be a struct type, and must have all its properties tagged and be -// a 1:1 match with the attributes reported by `typ`. FromStruct will recurse -// into FromValue for each attribute, using the type of the attribute as -// reported by `typ`. -// -// It is meant to be called through FromValue, not directly. -func FromStruct(ctx context.Context, typ attr.TypeWithAttributeTypes, val reflect.Value, path path.Path) (attr.Value, diag.Diagnostics) { - var diags diag.Diagnostics - objTypes := map[string]tftypes.Type{} - objValues := map[string]tftypes.Value{} - - // collect a map of fields that are defined in the tags of the struct - // passed in - targetFields, err := getStructTags(ctx, val, path) - if err != nil { - err = fmt.Errorf("error retrieving field names from struct tags: %w", err) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from struct value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return nil, diags - } - - attrTypes := typ.AttributeTypes() - - var objectMissing, structMissing []string - - for field := range targetFields { - if _, ok := attrTypes[field]; !ok { - objectMissing = append(objectMissing, field) - } - } - - for attrName, attrType := range attrTypes { - if attrType == nil { - objectMissing = append(objectMissing, attrName) - } - - if _, ok := targetFields[attrName]; !ok { - structMissing = append(structMissing, attrName) - } - } - - if len(objectMissing) > 0 || len(structMissing) > 0 { - missing := make([]string, 0, len(objectMissing)+len(structMissing)) - - if len(objectMissing) > 0 { - missing = append(missing, fmt.Sprintf("Struct defines fields not found in object: %s.", commaSeparatedString(objectMissing))) - } - - if len(structMissing) > 0 { - missing = append(missing, fmt.Sprintf("Object defines fields not found in struct: %s.", commaSeparatedString(structMissing))) - } - - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert from struct into an object. "+ - "This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - fmt.Sprintf("Mismatch between struct and object type: %s\n", strings.Join(missing, " "))+ - fmt.Sprintf("Struct: %s\n", val.Type())+ - fmt.Sprintf("Object type: %s", typ), - ) - - return nil, diags - } - - for name, fieldNo := range targetFields { - path := path.AtName(name) - fieldValue := val.Field(fieldNo) - - attrVal, attrValDiags := FromValue(ctx, attrTypes[name], fieldValue.Interface(), path) - diags.Append(attrValDiags...) - - if diags.HasError() { - return nil, diags - } - - tfObjVal, err := attrVal.ToTerraformValue(ctx) - if err != nil { - return nil, append(diags, toTerraformValueErrorDiag(err, path)) - } - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfObjVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - objValues[name] = tfObjVal - objTypes[name] = tfObjVal.Type() - } - - tfVal := tftypes.NewValue(tftypes.Object{ - AttributeTypes: objTypes, - }, objValues) - - if typeWithValidate, ok := typ.(xattr.TypeWithValidate); ok { - diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...) - - if diags.HasError() { - return nil, diags - } - } - - ret, err := typ.ValueFromTerraform(ctx, tfVal) - if err != nil { - return nil, append(diags, valueFromTerraformErrorDiag(err, path)) - } - - return ret, diags -} diff --git a/internal/provider/type_grant.go b/internal/provider/type_grant.go deleted file mode 100755 index d974376..0000000 --- a/internal/provider/type_grant.go +++ /dev/null @@ -1,17 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import "github.com/hashicorp/terraform-plugin-framework/types" - -type Grant struct { - CreatedAt types.String `tfsdk:"created_at"` - Deleted types.Bool `tfsdk:"deleted"` - GrantKitID types.String `tfsdk:"grant_kit_id"` - GrantKitVersionID types.String `tfsdk:"grant_kit_version_id"` - ID types.String `tfsdk:"id"` - OrganizationID types.String `tfsdk:"organization_id"` - RequestID types.String `tfsdk:"request_id"` - UpdatedAt types.String `tfsdk:"updated_at"` - UserID types.String `tfsdk:"user_id"` -} diff --git a/internal/provider/type_grant_workflow.go b/internal/provider/type_grant_workflow.go deleted file mode 100755 index 64c3c70..0000000 --- a/internal/provider/type_grant_workflow.go +++ /dev/null @@ -1,7 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -type GrantWorkflow struct { - Steps []Step `tfsdk:"steps"` -} diff --git a/internal/provider/type_policy.go b/internal/provider/type_policy.go deleted file mode 100755 index e75dd6e..0000000 --- a/internal/provider/type_policy.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import "github.com/hashicorp/terraform-plugin-framework/types" - -type Policy struct { - Bundle types.String `tfsdk:"bundle"` - Query types.String `tfsdk:"query"` -} diff --git a/internal/provider/type_request.go b/internal/provider/type_request.go deleted file mode 100755 index 867254c..0000000 --- a/internal/provider/type_request.go +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import "github.com/hashicorp/terraform-plugin-framework/types" - -type Request struct { - CreatedAt types.String `tfsdk:"created_at"` - GrantID types.String `tfsdk:"grant_id"` - GrantKitID types.String `tfsdk:"grant_kit_id"` - GrantKitName types.String `tfsdk:"grant_kit_name"` - GrantKitVersionID types.String `tfsdk:"grant_kit_version_id"` - ID types.String `tfsdk:"id"` - PullRequest types.String `tfsdk:"pull_request"` - Reason types.String `tfsdk:"reason"` - Reviews []Review `tfsdk:"reviews"` - Status types.String `tfsdk:"status"` - UpdatedAt types.String `tfsdk:"updated_at"` - UserID types.String `tfsdk:"user_id"` -} diff --git a/internal/provider/type_review.go b/internal/provider/type_review.go deleted file mode 100755 index 6d9c8b3..0000000 --- a/internal/provider/type_review.go +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import "github.com/hashicorp/terraform-plugin-framework/types" - -type Review struct { - CreatedAt types.String `tfsdk:"created_at"` - Grant *Grant `tfsdk:"grant"` - GrantID types.String `tfsdk:"grant_id"` - GrantKitName types.String `tfsdk:"grant_kit_name"` - GrantKitVersionID types.String `tfsdk:"grant_kit_version_id"` - ID types.String `tfsdk:"id"` - PullRequest types.String `tfsdk:"pull_request"` - Reason types.String `tfsdk:"reason"` - RequestID types.String `tfsdk:"request_id"` - Status types.String `tfsdk:"status"` - UpdatedAt types.String `tfsdk:"updated_at"` - UserEmail types.String `tfsdk:"user_email"` - UserID types.String `tfsdk:"user_id"` -} diff --git a/internal/provider/type_reviewers.go b/internal/provider/type_reviewers.go deleted file mode 100755 index b063f44..0000000 --- a/internal/provider/type_reviewers.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import "github.com/hashicorp/terraform-plugin-framework/types" - -type Reviewers struct { - AllOf []types.String `tfsdk:"all_of"` - OneOf []types.String `tfsdk:"one_of"` -} diff --git a/internal/provider/type_step.go b/internal/provider/type_step.go deleted file mode 100755 index e05cdb4..0000000 --- a/internal/provider/type_step.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -type Step struct { - Reviewers *Reviewers `tfsdk:"reviewers"` - SkipIf []Policy `tfsdk:"skip_if"` -} diff --git a/internal/provider/utils.go b/internal/provider/utils.go deleted file mode 100755 index b44ef79..0000000 --- a/internal/provider/utils.go +++ /dev/null @@ -1,81 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package provider - -import ( - tfReflect "abbey/v2/internal/provider/reflect" - "context" - "encoding/json" - "fmt" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" - "net/http" - "net/http/httputil" - "reflect" -) - -func debugResponse(response *http.Response) string { - dumpReq, err := httputil.DumpRequest(response.Request, false) - if err != nil { - return err.Error() - } - dumpRes, err := httputil.DumpResponse(response, true) - if err != nil { - dumpRes, err = httputil.DumpResponse(response, false) - if err != nil { - return err.Error() - } - } - return fmt.Sprintf("**Request**:\n%s\n**Response**:\n%s", string(dumpReq), string(dumpRes)) -} - -func reflectJSONKey(data any, key string) reflect.Value { - jsonIfied, err := json.Marshal(data) - if err != nil { - panic(fmt.Errorf("failed to marshal data: %w", err)) - } - var jsonMap map[string]interface{} - err = json.Unmarshal(jsonIfied, &jsonMap) - if err != nil { - panic(fmt.Errorf("failed to unmarshal data: %w", err)) - } - return reflect.ValueOf(jsonMap[key]) -} - -func merge(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse, target interface{}) { - var plan types.Object - var state types.Object - - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(state.As(ctx, target, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - - // we need a tftypes.Value for this Object to be able to use it with - // our reflection code - obj := types.ObjectType{AttrTypes: plan.AttributeTypes(ctx)} - val, err := plan.ToTerraformValue(ctx) - if err != nil { - resp.Diagnostics.Append(diag.NewErrorDiagnostic("Object Conversion Error", "An unexpected error was encountered trying to convert object. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error())) - return - } - resp.Diagnostics.Append(tfReflect.Into(ctx, obj, val, target, tfReflect.Options{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - }, path.Empty())...) -} diff --git a/internal/sdk/apikeys.go b/internal/sdk/apikeys.go deleted file mode 100755 index 4ba6a2a..0000000 --- a/internal/sdk/apikeys.go +++ /dev/null @@ -1,239 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// apiKeys - API Keys are used to authenticate to the Abbey API. -// -// https://docs.abbey.io/product/managing-api-keys -type apiKeys struct { - sdkConfiguration sdkConfiguration -} - -func newAPIKeys(sdkConfig sdkConfiguration) *apiKeys { - return &apiKeys{ - sdkConfiguration: sdkConfig, - } -} - -// CreateAPIKey - Create an API Key -// Creates a new API Key -func (s *apiKeys) CreateAPIKey(ctx context.Context, request shared.APIKeysCreateParams) (*operations.CreateAPIKeyResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/api-keys" - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "Request", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.CreateAPIKeyResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 201: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.APIKey - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.APIKey = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetAPIKeys - List API Keys -// Returns a list of a user's API Keys. -func (s *apiKeys) GetAPIKeys(ctx context.Context) (*operations.GetAPIKeysResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/api-keys" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetAPIKeysResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.APIKeys - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.APIKeys = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// DeleteAPIKey - Delete an API Key -// Delete a specified API Key. -func (s *apiKeys) DeleteAPIKey(ctx context.Context, request operations.DeleteAPIKeyRequest) (*operations.DeleteAPIKeyResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/api-keys/{api_key}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "DELETE", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.DeleteAPIKeyResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 204: - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/connections.go b/internal/sdk/connections.go deleted file mode 100755 index 20d81e6..0000000 --- a/internal/sdk/connections.go +++ /dev/null @@ -1,337 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// connections - Connections are authenticated, with scopes if available, and made available to Abbey Grant Kits at runtime. -// -// https://docs.abbey.io -type connections struct { - sdkConfiguration sdkConfiguration -} - -func newConnections(sdkConfig sdkConfiguration) *connections { - return &connections{ - sdkConfiguration: sdkConfig, - } -} - -// CreateConnection - Create a Connection -// Creates a new connection. -// -// Connections are authenticated, with scopes if available, and made available to Abbey Grant Kits at runtime. -func (s *connections) CreateConnection(ctx context.Context, request shared.ConnectionParams) (*operations.CreateConnectionResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/connections" - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "Request", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.CreateConnectionResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 201: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Connection - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Connection = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetConnection - Retrieve a Connection by ID -// Returns the details of a connection. -func (s *connections) GetConnection(ctx context.Context, request operations.GetConnectionRequest) (*operations.GetConnectionResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/connections/{connection_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetConnectionResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Connection - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Connection = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// ListConnections - List Connections -// Returns a list of connections. -// The connections are returned sorted by creation date, descending. -func (s *connections) ListConnections(ctx context.Context) (*operations.ListConnectionsResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/connections" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ListConnectionsResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.ConnectionListing - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.ConnectionListing = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// UpdateConnection - Update a Connection -// Updates the specified connection. -func (s *connections) UpdateConnection(ctx context.Context, request operations.UpdateConnectionRequest) (*operations.UpdateConnectionResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/connections/{connection_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "ConnectionUpdateParams", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "PUT", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.UpdateConnectionResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Connection - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Connection = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/connectionspecs.go b/internal/sdk/connectionspecs.go deleted file mode 100755 index 6c4a3bf..0000000 --- a/internal/sdk/connectionspecs.go +++ /dev/null @@ -1,97 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// connectionSpecs - Connection Specs are the templates for creating connections. -// They are used to validate connection parameters and to provide a UI for creating connections. -// -// https://docs.abbey.io -type connectionSpecs struct { - sdkConfiguration sdkConfiguration -} - -func newConnectionSpecs(sdkConfig sdkConfiguration) *connectionSpecs { - return &connectionSpecs{ - sdkConfiguration: sdkConfig, - } -} - -// ListConnectionSpecs - List Connection Specs -// Returns a list of connection specs. -// The connection specs are returned sorted alphabetically. -func (s *connectionSpecs) ListConnectionSpecs(ctx context.Context) (*operations.ListConnectionSpecsResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/connection-specs" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ListConnectionSpecsResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.ConnectionSpecListing - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.ConnectionSpecListing = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/demo.go b/internal/sdk/demo.go deleted file mode 100755 index ac0415d..0000000 --- a/internal/sdk/demo.go +++ /dev/null @@ -1,258 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// demo - Abbey Demo -// https://docs.abbey.io/getting-started/quickstart -type demo struct { - sdkConfiguration sdkConfiguration -} - -func newDemo(sdkConfig sdkConfiguration) *demo { - return &demo{ - sdkConfiguration: sdkConfig, - } -} - -// CreateDemo - Create Demo Access -// Creates a new Demo access -func (s *demo) CreateDemo(ctx context.Context, request shared.DemoParams) (*operations.CreateDemoResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/demo" - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "Request", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.CreateDemoResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 201: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Demo - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Demo = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// DeleteDemo - Delete Demo Access -// Deletes the Demo access -func (s *demo) DeleteDemo(ctx context.Context, request shared.DemoParams) (*operations.DeleteDemoResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/demo" - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "Request", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "DELETE", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.DeleteDemoResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Demo - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Demo = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetDemo - Get Demo -// Get the demo response -func (s *demo) GetDemo(ctx context.Context, request operations.GetDemoRequest) (*operations.GetDemoResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/demo" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - if err := utils.PopulateQueryParams(ctx, req, request, nil); err != nil { - return nil, fmt.Errorf("error populating query params: %w", err) - } - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetDemoResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Demo - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Demo = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 403: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/grantkits.go b/internal/sdk/grantkits.go deleted file mode 100755 index a46278b..0000000 --- a/internal/sdk/grantkits.go +++ /dev/null @@ -1,487 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// grantKits - Grant Kits are what you configure in code to control and automatically right-size permissions for resources. -// A Grant Kit has 3 components: -// -// 1. Workflow to configure how someone should get access. -// 2. Policies to configure if someone should get access. -// 3. Output to configure how and where Grants should materialize. -// -// https://docs.abbey.io/getting-started/concepts#grant-kits -type grantKits struct { - sdkConfiguration sdkConfiguration -} - -func newGrantKits(sdkConfig sdkConfiguration) *grantKits { - return &grantKits{ - sdkConfiguration: sdkConfig, - } -} - -// CreateGrantKit - Create a Grant Kit -// Creates a new Grant Kit -func (s *grantKits) CreateGrantKit(ctx context.Context, request shared.GrantKitCreateParams) (*operations.CreateGrantKitResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/grant-kits" - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "Request", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.CreateGrantKitResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 201: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.GrantKit - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.GrantKit = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// ListGrantKits - List Grant Kits -// Returns a list of the latest versions of each grant kit in the organization. -// -// Grant Kits are sorted by creation date, descending. -func (s *grantKits) ListGrantKits(ctx context.Context) (*operations.ListGrantKitsResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/grant-kits" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ListGrantKitsResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out []shared.GrantKit - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.GrantKits = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// DeleteGrantKit - Delete a Grant Kit -// Deletes the specified grant kit. -func (s *grantKits) DeleteGrantKit(ctx context.Context, request operations.DeleteGrantKitRequest) (*operations.DeleteGrantKitResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/grant-kits/{grant_kit_id_or_name}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "DELETE", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.DeleteGrantKitResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.GrantKit - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.GrantKit = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetGrantKitByID - Retrieve a Grant Kit by ID -// Returns the details of a Grant Kit. -func (s *grantKits) GetGrantKitByID(ctx context.Context, request operations.GetGrantKitByIDRequest) (*operations.GetGrantKitByIDResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/grant-kits/{grant_kit_id_or_name}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetGrantKitByIDResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.GrantKit - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.GrantKit = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// ListGrantKitVersionsByID - List Grant Kit Versions of a Grant Kit ID -// Returns all versions of a grant kit. -// -// Grant Kits are sorted by creation date, descending. -func (s *grantKits) ListGrantKitVersionsByID(ctx context.Context, request operations.ListGrantKitVersionsByIDRequest) (*operations.ListGrantKitVersionsByIDResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/grant-kits/{grant_kit_id_or_name}/versions", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ListGrantKitVersionsByIDResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out []shared.GrantKitVersion - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.GrantKitVersions = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// UpdateGrantKit - Update a Grant Kit -// Updates the specified grant kit. -func (s *grantKits) UpdateGrantKit(ctx context.Context, request operations.UpdateGrantKitRequest) (*operations.UpdateGrantKitResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/grant-kits/{grant_kit_id_or_name}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "GrantKitUpdateParams", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "PUT", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.UpdateGrantKitResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.GrantKit - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.GrantKit = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/grants.go b/internal/sdk/grants.go deleted file mode 100755 index cb9f056..0000000 --- a/internal/sdk/grants.go +++ /dev/null @@ -1,249 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// grants - Grants are permissions that reflect the result of an access request going through the process of evaluating -// policies and approval workflows where all approval conditions are met. -// -// Grants may be revoked manually by a user or automatically if a time-based or attribute-based policy is -// included in the corresponding Grant Kit's policy. -// -// https://docs.abbey.io/getting-started/concepts#grants -type grants struct { - sdkConfiguration sdkConfiguration -} - -func newGrants(sdkConfig sdkConfiguration) *grants { - return &grants{ - sdkConfiguration: sdkConfig, - } -} - -// ListGrants - List Grants -// Returns a list of all the grants belonging to a user. -// -// Grants are sorted by creation date, descending. Creation date effectively means when the grant was approved. -func (s *grants) ListGrants(ctx context.Context) (*operations.ListGrantsResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/grants" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ListGrantsResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out []shared.Grant - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Grants = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetGrantByID - Retrieve a Grant by ID -// Returns the details of a grant. -func (s *grants) GetGrantByID(ctx context.Context, request operations.GetGrantByIDRequest) (*operations.GetGrantByIDResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/grants/{grant_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetGrantByIDResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Grant - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Grant = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// RevokeGrant - Revoke a Grant by ID -// Revokes the specified grant. -func (s *grants) RevokeGrant(ctx context.Context, request operations.RevokeGrantRequest) (*operations.RevokeGrantResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/grants/{grant_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "DELETE", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.RevokeGrantResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Grant - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Grant = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/identities.go b/internal/sdk/identities.go deleted file mode 100755 index de94b2a..0000000 --- a/internal/sdk/identities.go +++ /dev/null @@ -1,329 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// identities - User metadata used for enriching data. -// Enriched data is used to write richer policies, workflows, and outputs. -// -// https://docs.abbey.io -type identities struct { - sdkConfiguration sdkConfiguration -} - -func newIdentities(sdkConfig sdkConfiguration) *identities { - return &identities{ - sdkConfiguration: sdkConfig, - } -} - -// CreateIdentity - Create an Identity -// Creates a new identity. -// -// An identity represents a human, service, or workload. -func (s *identities) CreateIdentity(ctx context.Context, request shared.IdentityParams) (*operations.CreateIdentityResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/identities" - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "Request", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.CreateIdentityResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 201: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Identity - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Identity = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// DeleteIdentity - Delete an Identity -// Deletes the specified identity. -func (s *identities) DeleteIdentity(ctx context.Context, request operations.DeleteIdentityRequest) (*operations.DeleteIdentityResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/identities/{identity_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "DELETE", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.DeleteIdentityResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetIdentity - Retrieve an Identity -// Returns the details of an identity. -func (s *identities) GetIdentity(ctx context.Context, request operations.GetIdentityRequest) (*operations.GetIdentityResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/identities/{identity_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetIdentityResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Identity - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Identity = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// UpdateIdentity - Update an Identity -// Updates an identity. -func (s *identities) UpdateIdentity(ctx context.Context, request operations.UpdateIdentityRequest) (*operations.UpdateIdentityResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/identities/{identity_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "IdentityParams", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "PUT", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.UpdateIdentityResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Identity - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Identity = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/pkg/models/operations/approvereview.go b/internal/sdk/pkg/models/operations/approvereview.go deleted file mode 100755 index 71f9e64..0000000 --- a/internal/sdk/pkg/models/operations/approvereview.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ApproveReviewRequest struct { - ReviewUpdateParams shared.ReviewUpdateParams `request:"mediaType=application/json"` - // The ID of the review to approve - ReviewID string `pathParam:"style=simple,explode=false,name=review_id"` -} - -type ApproveReviewResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Success - Review *shared.Review - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/cancelrequestbyid.go b/internal/sdk/pkg/models/operations/cancelrequestbyid.go deleted file mode 100755 index 62e1020..0000000 --- a/internal/sdk/pkg/models/operations/cancelrequestbyid.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type CancelRequestByIDRequest struct { - RequestCancelParams shared.RequestCancelParams `request:"mediaType=application/json"` - // The ID of the request to cancel - RequestID string `pathParam:"style=simple,explode=false,name=request_id"` -} - -type CancelRequestByIDResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Success - Request *shared.Request - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/createapikey.go b/internal/sdk/pkg/models/operations/createapikey.go deleted file mode 100755 index 381eeba..0000000 --- a/internal/sdk/pkg/models/operations/createapikey.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type CreateAPIKeyResponse struct { - // Created - APIKey *shared.APIKey - ContentType string - // Request Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/createconnection.go b/internal/sdk/pkg/models/operations/createconnection.go deleted file mode 100755 index bc43004..0000000 --- a/internal/sdk/pkg/models/operations/createconnection.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type CreateConnectionResponse struct { - // Created - Connection *shared.Connection - ContentType string - // Request Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/createdemo.go b/internal/sdk/pkg/models/operations/createdemo.go deleted file mode 100755 index 04ee410..0000000 --- a/internal/sdk/pkg/models/operations/createdemo.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type CreateDemoResponse struct { - ContentType string - // Created - Demo *shared.Demo - // Request Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/creategrantkit.go b/internal/sdk/pkg/models/operations/creategrantkit.go deleted file mode 100755 index db6772c..0000000 --- a/internal/sdk/pkg/models/operations/creategrantkit.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type CreateGrantKitResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Created - GrantKit *shared.GrantKit - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/createidentity.go b/internal/sdk/pkg/models/operations/createidentity.go deleted file mode 100755 index 12638e9..0000000 --- a/internal/sdk/pkg/models/operations/createidentity.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type CreateIdentityResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Created - Identity *shared.Identity - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/createrequest.go b/internal/sdk/pkg/models/operations/createrequest.go deleted file mode 100755 index 51b1271..0000000 --- a/internal/sdk/pkg/models/operations/createrequest.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type CreateRequestResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Created - Request *shared.Request - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/deleteapikey.go b/internal/sdk/pkg/models/operations/deleteapikey.go deleted file mode 100755 index c2434dc..0000000 --- a/internal/sdk/pkg/models/operations/deleteapikey.go +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type DeleteAPIKeyRequest struct { - // The API Key to delete. - APIKey string `pathParam:"style=simple,explode=false,name=api_key"` -} - -type DeleteAPIKeyResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/deletedemo.go b/internal/sdk/pkg/models/operations/deletedemo.go deleted file mode 100755 index e4b1368..0000000 --- a/internal/sdk/pkg/models/operations/deletedemo.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type DeleteDemoResponse struct { - ContentType string - // Success - Demo *shared.Demo - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/deletegrantkit.go b/internal/sdk/pkg/models/operations/deletegrantkit.go deleted file mode 100755 index edd68f2..0000000 --- a/internal/sdk/pkg/models/operations/deletegrantkit.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type DeleteGrantKitRequest struct { - // The ID of the grant kit or resource to delete - GrantKitIDOrName string `pathParam:"style=simple,explode=false,name=grant_kit_id_or_name"` -} - -type DeleteGrantKitResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - GrantKit *shared.GrantKit - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/deleteidentity.go b/internal/sdk/pkg/models/operations/deleteidentity.go deleted file mode 100755 index 7061c50..0000000 --- a/internal/sdk/pkg/models/operations/deleteidentity.go +++ /dev/null @@ -1,21 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type DeleteIdentityRequest struct { - // The ID of the identity to delete - IdentityID string `pathParam:"style=simple,explode=false,name=identity_id"` -} - -type DeleteIdentityResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/denyreview.go b/internal/sdk/pkg/models/operations/denyreview.go deleted file mode 100755 index 3d56b9a..0000000 --- a/internal/sdk/pkg/models/operations/denyreview.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type DenyReviewRequest struct { - ReviewUpdateParams shared.ReviewUpdateParams `request:"mediaType=application/json"` - // The ID of the review to deny - ReviewID string `pathParam:"style=simple,explode=false,name=review_id"` -} - -type DenyReviewResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Success - Review *shared.Review - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getapikeys.go b/internal/sdk/pkg/models/operations/getapikeys.go deleted file mode 100755 index 7168cfd..0000000 --- a/internal/sdk/pkg/models/operations/getapikeys.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetAPIKeysResponse struct { - // Success - APIKeys *shared.APIKeys - ContentType string - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getconnection.go b/internal/sdk/pkg/models/operations/getconnection.go deleted file mode 100755 index fd80303..0000000 --- a/internal/sdk/pkg/models/operations/getconnection.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetConnectionRequest struct { - // The ID of the connection to retrieve - ConnectionID string `pathParam:"style=simple,explode=false,name=connection_id"` -} - -type GetConnectionResponse struct { - // Success - Connection *shared.Connection - ContentType string - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getdemo.go b/internal/sdk/pkg/models/operations/getdemo.go deleted file mode 100755 index 34b8f68..0000000 --- a/internal/sdk/pkg/models/operations/getdemo.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetDemoRequest struct { - // The email of the user - Email string `queryParam:"style=form,explode=true,name=email"` -} - -type GetDemoResponse struct { - ContentType string - // Success - Demo *shared.Demo - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getgrantbyid.go b/internal/sdk/pkg/models/operations/getgrantbyid.go deleted file mode 100755 index 5723e6b..0000000 --- a/internal/sdk/pkg/models/operations/getgrantbyid.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetGrantByIDRequest struct { - // The ID of the grant to retrieve - GrantID string `pathParam:"style=simple,explode=false,name=grant_id"` -} - -type GetGrantByIDResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Grant *shared.Grant - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getgrantkitbyid.go b/internal/sdk/pkg/models/operations/getgrantkitbyid.go deleted file mode 100755 index 4cc383a..0000000 --- a/internal/sdk/pkg/models/operations/getgrantkitbyid.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetGrantKitByIDRequest struct { - // The ID of the grant kit or resource to retrieve. - GrantKitIDOrName string `pathParam:"style=simple,explode=false,name=grant_kit_id_or_name"` -} - -type GetGrantKitByIDResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - GrantKit *shared.GrantKit - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getidentity.go b/internal/sdk/pkg/models/operations/getidentity.go deleted file mode 100755 index 2860a96..0000000 --- a/internal/sdk/pkg/models/operations/getidentity.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetIdentityRequest struct { - // The ID of the identity to retrieve - IdentityID string `pathParam:"style=simple,explode=false,name=identity_id"` -} - -type GetIdentityResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Identity *shared.Identity - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getrequestbyid.go b/internal/sdk/pkg/models/operations/getrequestbyid.go deleted file mode 100755 index 657c541..0000000 --- a/internal/sdk/pkg/models/operations/getrequestbyid.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetRequestByIDRequest struct { - // The ID of the request to retrieve - RequestID string `pathParam:"style=simple,explode=false,name=request_id"` -} - -type GetRequestByIDResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Request *shared.Request - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/getreviewbyid.go b/internal/sdk/pkg/models/operations/getreviewbyid.go deleted file mode 100755 index b78c9b2..0000000 --- a/internal/sdk/pkg/models/operations/getreviewbyid.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type GetReviewByIDRequest struct { - // The ID of the review to retrieve. - ReviewID string `pathParam:"style=simple,explode=false,name=review_id"` -} - -type GetReviewByIDResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Review *shared.Review - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/listconnections.go b/internal/sdk/pkg/models/operations/listconnections.go deleted file mode 100755 index 3426a27..0000000 --- a/internal/sdk/pkg/models/operations/listconnections.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ListConnectionsResponse struct { - // Success - ConnectionListing *shared.ConnectionListing - ContentType string - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/listconnectionspecs.go b/internal/sdk/pkg/models/operations/listconnectionspecs.go deleted file mode 100755 index 193de3c..0000000 --- a/internal/sdk/pkg/models/operations/listconnectionspecs.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ListConnectionSpecsResponse struct { - // Success - ConnectionSpecListing *shared.ConnectionSpecListing - ContentType string - // Authentication Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/listgrantkits.go b/internal/sdk/pkg/models/operations/listgrantkits.go deleted file mode 100755 index 4df5c3c..0000000 --- a/internal/sdk/pkg/models/operations/listgrantkits.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ListGrantKitsResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - GrantKits []shared.GrantKit - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/listgrantkitversionsbyid.go b/internal/sdk/pkg/models/operations/listgrantkitversionsbyid.go deleted file mode 100755 index ebe3fe7..0000000 --- a/internal/sdk/pkg/models/operations/listgrantkitversionsbyid.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ListGrantKitVersionsByIDRequest struct { - // The ID of the grant kit or resource to retrieve. - GrantKitIDOrName string `pathParam:"style=simple,explode=false,name=grant_kit_id_or_name"` -} - -type ListGrantKitVersionsByIDResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - GrantKitVersions []shared.GrantKitVersion - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/listgrants.go b/internal/sdk/pkg/models/operations/listgrants.go deleted file mode 100755 index e4d0c52..0000000 --- a/internal/sdk/pkg/models/operations/listgrants.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ListGrantsResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Grants []shared.Grant - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/listrequests.go b/internal/sdk/pkg/models/operations/listrequests.go deleted file mode 100755 index 834bac2..0000000 --- a/internal/sdk/pkg/models/operations/listrequests.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ListRequestsResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Requests []shared.Request - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/listreviews.go b/internal/sdk/pkg/models/operations/listreviews.go deleted file mode 100755 index 1d85442..0000000 --- a/internal/sdk/pkg/models/operations/listreviews.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type ListReviewsResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Reviews []shared.Review - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/revokegrant.go b/internal/sdk/pkg/models/operations/revokegrant.go deleted file mode 100755 index bffe863..0000000 --- a/internal/sdk/pkg/models/operations/revokegrant.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type RevokeGrantRequest struct { - // The ID of the grant to revoke - GrantID string `pathParam:"style=simple,explode=false,name=grant_id"` -} - -type RevokeGrantResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Success - Grant *shared.Grant - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/updateconnection.go b/internal/sdk/pkg/models/operations/updateconnection.go deleted file mode 100755 index ba58f6a..0000000 --- a/internal/sdk/pkg/models/operations/updateconnection.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type UpdateConnectionRequest struct { - ConnectionUpdateParams shared.ConnectionUpdateParams `request:"mediaType=application/json"` - // The ID of the connection to update - ConnectionID string `pathParam:"style=simple,explode=false,name=connection_id"` -} - -type UpdateConnectionResponse struct { - // Success - Connection *shared.Connection - ContentType string - // Request Failed - Error *shared.Error - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/updategrantkit.go b/internal/sdk/pkg/models/operations/updategrantkit.go deleted file mode 100755 index 464c90c..0000000 --- a/internal/sdk/pkg/models/operations/updategrantkit.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type UpdateGrantKitRequest struct { - GrantKitUpdateParams shared.GrantKitUpdateParams `request:"mediaType=application/json"` - // The ID of the grant kit or resource to update - GrantKitIDOrName string `pathParam:"style=simple,explode=false,name=grant_kit_id_or_name"` -} - -type UpdateGrantKitResponse struct { - ContentType string - // Request Failed - Error *shared.Error - // Success - GrantKit *shared.GrantKit - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/operations/updateidentity.go b/internal/sdk/pkg/models/operations/updateidentity.go deleted file mode 100755 index ffb6532..0000000 --- a/internal/sdk/pkg/models/operations/updateidentity.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package operations - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "net/http" -) - -type UpdateIdentityRequest struct { - IdentityParams shared.IdentityParams `request:"mediaType=application/json"` - // The ID of the identity to retrieve - IdentityID string `pathParam:"style=simple,explode=false,name=identity_id"` -} - -type UpdateIdentityResponse struct { - ContentType string - // Authentication Failed - Error *shared.Error - // Success - Identity *shared.Identity - StatusCode int - RawResponse *http.Response -} diff --git a/internal/sdk/pkg/models/shared/apikey.go b/internal/sdk/pkg/models/shared/apikey.go deleted file mode 100755 index 145c722..0000000 --- a/internal/sdk/pkg/models/shared/apikey.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// APIKey - Created -type APIKey struct { - APIKey string `json:"api_key"` - Expired bool `json:"expired"` - ExpiredAt *time.Time `json:"expired_at,omitempty"` - LastUsed *time.Time `json:"last_used,omitempty"` - Name string `json:"name"` -} diff --git a/internal/sdk/pkg/models/shared/apikeys.go b/internal/sdk/pkg/models/shared/apikeys.go deleted file mode 100755 index b165eff..0000000 --- a/internal/sdk/pkg/models/shared/apikeys.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -// APIKeys - Success -type APIKeys struct { - Items []APIKey `json:"items"` -} diff --git a/internal/sdk/pkg/models/shared/apikeyscreateparams.go b/internal/sdk/pkg/models/shared/apikeyscreateparams.go deleted file mode 100755 index d60b62f..0000000 --- a/internal/sdk/pkg/models/shared/apikeyscreateparams.go +++ /dev/null @@ -1,12 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -type APIKeysCreateParams struct { - ExpiredAt *time.Time `json:"expired_at,omitempty"` - Name string `json:"name"` -} diff --git a/internal/sdk/pkg/models/shared/connection.go b/internal/sdk/pkg/models/shared/connection.go deleted file mode 100755 index 2501a0d..0000000 --- a/internal/sdk/pkg/models/shared/connection.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// Connection - Created -type Connection struct { - CreatedAt time.Time `json:"created_at"` - ID string `json:"id"` - Name *string `json:"name,omitempty"` - Type ConnectionType `json:"type"` -} diff --git a/internal/sdk/pkg/models/shared/connectionauth.go b/internal/sdk/pkg/models/shared/connectionauth.go deleted file mode 100755 index c9a2792..0000000 --- a/internal/sdk/pkg/models/shared/connectionauth.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" -) - -type ConnectionAuthType string - -const ( - ConnectionAuthTypeOauth2 ConnectionAuthType = "Oauth2" -) - -type ConnectionAuth struct { - Oauth2Flow *Oauth2Flow - - Type ConnectionAuthType -} - -func CreateConnectionAuthOauth2(oauth2 Oauth2Flow) ConnectionAuth { - typ := ConnectionAuthTypeOauth2 - typStr := ConnectionAuthTypeEnum(typ) - oauth2.ConnectionAuthTypeEnum = &typStr - - return ConnectionAuth{ - Oauth2Flow: &oauth2, - Type: typ, - } -} - -func (u *ConnectionAuth) UnmarshalJSON(data []byte) error { - var d *json.Decoder - - type discriminator struct { - ConnectionAuthTypeEnum string - } - - dis := new(discriminator) - if err := json.Unmarshal(data, &dis); err != nil { - return fmt.Errorf("could not unmarshal discriminator: %w", err) - } - - switch dis.ConnectionAuthTypeEnum { - case "Oauth2": - d = json.NewDecoder(bytes.NewReader(data)) - oauth2Flow := new(Oauth2Flow) - if err := d.Decode(&oauth2Flow); err != nil { - return fmt.Errorf("could not unmarshal expected type: %w", err) - } - - u.Oauth2Flow = oauth2Flow - u.Type = ConnectionAuthTypeOauth2 - return nil - } - - return errors.New("could not unmarshal into supported union types") -} - -func (u ConnectionAuth) MarshalJSON() ([]byte, error) { - if u.Oauth2Flow != nil { - return json.Marshal(u.Oauth2Flow) - } - - return nil, nil -} diff --git a/internal/sdk/pkg/models/shared/connectionauthtypeenum.go b/internal/sdk/pkg/models/shared/connectionauthtypeenum.go deleted file mode 100755 index d02a993..0000000 --- a/internal/sdk/pkg/models/shared/connectionauthtypeenum.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type ConnectionAuthTypeEnum string - -const ( - ConnectionAuthTypeEnumOauth2 ConnectionAuthTypeEnum = "Oauth2" -) - -func (e ConnectionAuthTypeEnum) ToPointer() *ConnectionAuthTypeEnum { - return &e -} - -func (e *ConnectionAuthTypeEnum) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "Oauth2": - *e = ConnectionAuthTypeEnum(v) - return nil - default: - return fmt.Errorf("invalid value for ConnectionAuthTypeEnum: %v", v) - } -} diff --git a/internal/sdk/pkg/models/shared/connectionlisting.go b/internal/sdk/pkg/models/shared/connectionlisting.go deleted file mode 100755 index 3bfe855..0000000 --- a/internal/sdk/pkg/models/shared/connectionlisting.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -// ConnectionListing - Success -type ConnectionListing struct { - Items []Connection `json:"items"` - Next *string `json:"next,omitempty"` - Prev *string `json:"prev,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/connectionparams.go b/internal/sdk/pkg/models/shared/connectionparams.go deleted file mode 100755 index 8b7fe66..0000000 --- a/internal/sdk/pkg/models/shared/connectionparams.go +++ /dev/null @@ -1,96 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" -) - -type ConnectionParamsType string - -const ( - ConnectionParamsTypeGithub ConnectionParamsType = "Github" - ConnectionParamsTypePagerduty ConnectionParamsType = "Pagerduty" -) - -type ConnectionParams struct { - ConnectionParamsGithubVariant *ConnectionParamsGithubVariant - PagerdutyConnectionValue *PagerdutyConnectionValue - - Type ConnectionParamsType -} - -func CreateConnectionParamsGithub(github ConnectionParamsGithubVariant) ConnectionParams { - typ := ConnectionParamsTypeGithub - typStr := ConnectionType(typ) - github.Type = typStr - - return ConnectionParams{ - ConnectionParamsGithubVariant: &github, - Type: typ, - } -} - -func CreateConnectionParamsPagerduty(pagerduty PagerdutyConnectionValue) ConnectionParams { - typ := ConnectionParamsTypePagerduty - typStr := ConnectionType(typ) - pagerduty.Type = typStr - - return ConnectionParams{ - PagerdutyConnectionValue: &pagerduty, - Type: typ, - } -} - -func (u *ConnectionParams) UnmarshalJSON(data []byte) error { - var d *json.Decoder - - type discriminator struct { - Type string - } - - dis := new(discriminator) - if err := json.Unmarshal(data, &dis); err != nil { - return fmt.Errorf("could not unmarshal discriminator: %w", err) - } - - switch dis.Type { - case "Github": - d = json.NewDecoder(bytes.NewReader(data)) - connectionParamsGithubVariant := new(ConnectionParamsGithubVariant) - if err := d.Decode(&connectionParamsGithubVariant); err != nil { - return fmt.Errorf("could not unmarshal expected type: %w", err) - } - - u.ConnectionParamsGithubVariant = connectionParamsGithubVariant - u.Type = ConnectionParamsTypeGithub - return nil - case "Pagerduty": - d = json.NewDecoder(bytes.NewReader(data)) - pagerdutyConnectionValue := new(PagerdutyConnectionValue) - if err := d.Decode(&pagerdutyConnectionValue); err != nil { - return fmt.Errorf("could not unmarshal expected type: %w", err) - } - - u.PagerdutyConnectionValue = pagerdutyConnectionValue - u.Type = ConnectionParamsTypePagerduty - return nil - } - - return errors.New("could not unmarshal into supported union types") -} - -func (u ConnectionParams) MarshalJSON() ([]byte, error) { - if u.ConnectionParamsGithubVariant != nil { - return json.Marshal(u.ConnectionParamsGithubVariant) - } - - if u.PagerdutyConnectionValue != nil { - return json.Marshal(u.PagerdutyConnectionValue) - } - - return nil, nil -} diff --git a/internal/sdk/pkg/models/shared/connectionparamsgithub.go b/internal/sdk/pkg/models/shared/connectionparamsgithub.go deleted file mode 100755 index afd535d..0000000 --- a/internal/sdk/pkg/models/shared/connectionparamsgithub.go +++ /dev/null @@ -1,7 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type ConnectionParamsGithub struct { - InstallationID string `json:"installation_id"` -} diff --git a/internal/sdk/pkg/models/shared/connectionparamsgithubvariant.go b/internal/sdk/pkg/models/shared/connectionparamsgithubvariant.go deleted file mode 100755 index dfbc8e8..0000000 --- a/internal/sdk/pkg/models/shared/connectionparamsgithubvariant.go +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type ConnectionParamsGithubVariant struct { - Name *string `json:"name,omitempty"` - Type ConnectionType `json:"type"` - Value ConnectionParamsGithub `json:"value"` -} diff --git a/internal/sdk/pkg/models/shared/connectionrequestspec.go b/internal/sdk/pkg/models/shared/connectionrequestspec.go deleted file mode 100755 index 8e75192..0000000 --- a/internal/sdk/pkg/models/shared/connectionrequestspec.go +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type ConnectionRequestSpec struct { - // A value conforming to the official JSON Schema core/validation dialect 2020-12 meta-schema. - // - Body interface{} `json:"body,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/connectionspec.go b/internal/sdk/pkg/models/shared/connectionspec.go deleted file mode 100755 index b8ba2fb..0000000 --- a/internal/sdk/pkg/models/shared/connectionspec.go +++ /dev/null @@ -1,11 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type ConnectionSpec struct { - Auth ConnectionAuth `json:"auth"` - Icon string `json:"icon"` - ID string `json:"id"` - Name string `json:"name"` - Request ConnectionRequestSpec `json:"request"` -} diff --git a/internal/sdk/pkg/models/shared/connectionspeclisting.go b/internal/sdk/pkg/models/shared/connectionspeclisting.go deleted file mode 100755 index b0f46f3..0000000 --- a/internal/sdk/pkg/models/shared/connectionspeclisting.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -// ConnectionSpecListing - Success -type ConnectionSpecListing struct { - Items []ConnectionSpec `json:"items"` - Next *string `json:"next,omitempty"` - Prev *string `json:"prev,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/connectiontype.go b/internal/sdk/pkg/models/shared/connectiontype.go deleted file mode 100755 index 1ba1d91..0000000 --- a/internal/sdk/pkg/models/shared/connectiontype.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type ConnectionType string - -const ( - ConnectionTypeGithub ConnectionType = "Github" - ConnectionTypePagerduty ConnectionType = "Pagerduty" -) - -func (e ConnectionType) ToPointer() *ConnectionType { - return &e -} - -func (e *ConnectionType) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "Github": - fallthrough - case "Pagerduty": - *e = ConnectionType(v) - return nil - default: - return fmt.Errorf("invalid value for ConnectionType: %v", v) - } -} diff --git a/internal/sdk/pkg/models/shared/connectionupdateparams.go b/internal/sdk/pkg/models/shared/connectionupdateparams.go deleted file mode 100755 index a1e216c..0000000 --- a/internal/sdk/pkg/models/shared/connectionupdateparams.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type ConnectionUpdateParams struct { - // The name of the connection - Name *string `json:"name,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/demo.go b/internal/sdk/pkg/models/shared/demo.go deleted file mode 100755 index fd0c91f..0000000 --- a/internal/sdk/pkg/models/shared/demo.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// Demo - Success -type Demo struct { - CreatedAt *time.Time `json:"created_at,omitempty"` - ID *int64 `json:"id,omitempty"` - UpdatedAt *time.Time `json:"updated_at,omitempty"` - UserID *string `json:"user_id,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/demoparams.go b/internal/sdk/pkg/models/shared/demoparams.go deleted file mode 100755 index 4df2060..0000000 --- a/internal/sdk/pkg/models/shared/demoparams.go +++ /dev/null @@ -1,37 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type DemoParamsPermission string - -const ( - DemoParamsPermissionReadWrite DemoParamsPermission = "read_write" -) - -func (e DemoParamsPermission) ToPointer() *DemoParamsPermission { - return &e -} - -func (e *DemoParamsPermission) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "read_write": - *e = DemoParamsPermission(v) - return nil - default: - return fmt.Errorf("invalid value for DemoParamsPermission: %v", v) - } -} - -type DemoParams struct { - Email string `json:"email"` - Permission DemoParamsPermission `json:"permission"` -} diff --git a/internal/sdk/pkg/models/shared/error.go b/internal/sdk/pkg/models/shared/error.go deleted file mode 100755 index b8ec694..0000000 --- a/internal/sdk/pkg/models/shared/error.go +++ /dev/null @@ -1,12 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -// Error - Authentication Failed -type Error struct { - Code string `json:"code"` - DocURL *string `json:"doc_url,omitempty"` - Message string `json:"message"` - Param *string `json:"param,omitempty"` - Type string `json:"type"` -} diff --git a/internal/sdk/pkg/models/shared/grant.go b/internal/sdk/pkg/models/shared/grant.go deleted file mode 100755 index 8e54d58..0000000 --- a/internal/sdk/pkg/models/shared/grant.go +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// Grant - Success -type Grant struct { - CreatedAt time.Time `json:"created_at"` - Deleted bool `json:"deleted"` - GrantKitID string `json:"grant_kit_id"` - GrantKitVersionID string `json:"grant_kit_version_id"` - ID string `json:"id"` - OrganizationID string `json:"organization_id"` - RequestID string `json:"request_id"` - UpdatedAt time.Time `json:"updated_at"` - UserID string `json:"user_id"` -} diff --git a/internal/sdk/pkg/models/shared/grantkit.go b/internal/sdk/pkg/models/shared/grantkit.go deleted file mode 100755 index 64220e9..0000000 --- a/internal/sdk/pkg/models/shared/grantkit.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// GrantKit - Created -type GrantKit struct { - CreatedAt time.Time `json:"created_at"` - CurrentVersionID string `json:"current_version_id"` - Description string `json:"description"` - Grants []Grant `json:"grants"` - ID string `json:"id"` - Name string `json:"name"` - Output Output `json:"output"` - Policies []Policy `json:"policies,omitempty"` - Requests []Request `json:"requests"` - UpdatedAt time.Time `json:"updated_at"` - Workflow *GrantWorkflow `json:"workflow,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/grantkitcreateparams.go b/internal/sdk/pkg/models/shared/grantkitcreateparams.go deleted file mode 100755 index 58abeee..0000000 --- a/internal/sdk/pkg/models/shared/grantkitcreateparams.go +++ /dev/null @@ -1,11 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type GrantKitCreateParams struct { - Description string `json:"description"` - Name string `json:"name"` - Output Output `json:"output"` - Policies []Policy `json:"policies,omitempty"` - Workflow *GrantWorkflow `json:"workflow,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/grantkitupdateparams.go b/internal/sdk/pkg/models/shared/grantkitupdateparams.go deleted file mode 100755 index 7ee2100..0000000 --- a/internal/sdk/pkg/models/shared/grantkitupdateparams.go +++ /dev/null @@ -1,12 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type GrantKitUpdateParams struct { - Description string `json:"description"` - // The name of the connection - Name string `json:"name"` - Output Output `json:"output"` - Policies []Policy `json:"policies,omitempty"` - Workflow *GrantWorkflow `json:"workflow,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/grantkitversion.go b/internal/sdk/pkg/models/shared/grantkitversion.go deleted file mode 100755 index d21388c..0000000 --- a/internal/sdk/pkg/models/shared/grantkitversion.go +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -type GrantKitVersion struct { - CreatedAt time.Time `json:"created_at"` - Description string `json:"description"` - GrantKitID string `json:"grant_kit_id"` - GrantKitName string `json:"grant_kit_name"` - ID string `json:"id"` - Output Output `json:"output"` - Policies []Policy `json:"policies"` - UpdatedAt time.Time `json:"updated_at"` - Version int64 `json:"version"` - Workflow GrantWorkflow `json:"workflow"` -} diff --git a/internal/sdk/pkg/models/shared/grantworkflow.go b/internal/sdk/pkg/models/shared/grantworkflow.go deleted file mode 100755 index 69f5acd..0000000 --- a/internal/sdk/pkg/models/shared/grantworkflow.go +++ /dev/null @@ -1,7 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type GrantWorkflow struct { - Steps []Step `json:"steps,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/httpmethod.go b/internal/sdk/pkg/models/shared/httpmethod.go deleted file mode 100755 index 348430e..0000000 --- a/internal/sdk/pkg/models/shared/httpmethod.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type HTTPMethod string - -const ( - HTTPMethodGet HTTPMethod = "GET" - HTTPMethodPost HTTPMethod = "POST" -) - -func (e HTTPMethod) ToPointer() *HTTPMethod { - return &e -} - -func (e *HTTPMethod) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "GET": - fallthrough - case "POST": - *e = HTTPMethod(v) - return nil - default: - return fmt.Errorf("invalid value for HTTPMethod: %v", v) - } -} diff --git a/internal/sdk/pkg/models/shared/identity.go b/internal/sdk/pkg/models/shared/identity.go deleted file mode 100755 index 7ae3090..0000000 --- a/internal/sdk/pkg/models/shared/identity.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// Identity - Created -type Identity struct { - AbbeyAccount string `json:"abbey_account"` - CreatedAt time.Time `json:"created_at"` - ID string `json:"id"` - // Json encoded string. See documentation for details. - Metadata string `json:"metadata"` - Source string `json:"source"` - UpdatedAt time.Time `json:"updated_at"` -} diff --git a/internal/sdk/pkg/models/shared/identityparams.go b/internal/sdk/pkg/models/shared/identityparams.go deleted file mode 100755 index 8229508..0000000 --- a/internal/sdk/pkg/models/shared/identityparams.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type IdentityParams struct { - AbbeyAccount string `json:"abbey_account"` - // Json encoded string. See documentation for details. - Metadata string `json:"metadata"` - Source string `json:"source"` -} diff --git a/internal/sdk/pkg/models/shared/keyvaluepair.go b/internal/sdk/pkg/models/shared/keyvaluepair.go deleted file mode 100755 index a73a53c..0000000 --- a/internal/sdk/pkg/models/shared/keyvaluepair.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type KeyValuePair struct { - Key string `json:"key"` - // A meta-schema conforming to the official JSON Schema core/validation dialect 2020-12 meta-schema. - // - Value interface{} `json:"value,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/oauth2flow.go b/internal/sdk/pkg/models/shared/oauth2flow.go deleted file mode 100755 index 5611dfd..0000000 --- a/internal/sdk/pkg/models/shared/oauth2flow.go +++ /dev/null @@ -1,14 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type Oauth2Flow struct { - CallbackQueryParams []string `json:"callback_query_params,omitempty"` - ConnectionAuthTypeEnum *ConnectionAuthTypeEnum `json:"type,omitempty"` - // Describes how the client should conduct the authorization code exchange. - // - Exchange *Oauth2FlowExchange `json:"exchange,omitempty"` - Pkce *Oauth2FlowPkce `json:"pkce,omitempty"` - QueryParams []KeyValuePair `json:"query_params,omitempty"` - URL string `json:"url"` -} diff --git a/internal/sdk/pkg/models/shared/oauth2flowexchange.go b/internal/sdk/pkg/models/shared/oauth2flowexchange.go deleted file mode 100755 index 4375691..0000000 --- a/internal/sdk/pkg/models/shared/oauth2flowexchange.go +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -// Oauth2FlowExchange - Describes how the client should conduct the authorization code exchange. -type Oauth2FlowExchange struct { - Enabled bool `json:"enabled"` - Request RequestSpec `json:"request"` -} diff --git a/internal/sdk/pkg/models/shared/oauth2flowpkce.go b/internal/sdk/pkg/models/shared/oauth2flowpkce.go deleted file mode 100755 index 2ab7ef2..0000000 --- a/internal/sdk/pkg/models/shared/oauth2flowpkce.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type Oauth2FlowPkce struct { - Enabled bool `json:"enabled"` - Method PkceMethod `json:"method"` -} diff --git a/internal/sdk/pkg/models/shared/output.go b/internal/sdk/pkg/models/shared/output.go deleted file mode 100755 index c3a23ca..0000000 --- a/internal/sdk/pkg/models/shared/output.go +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type Output struct { - Append *string `json:"append,omitempty"` - Location string `json:"location"` - Overwrite *string `json:"overwrite,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/pagerdutyconnection.go b/internal/sdk/pkg/models/shared/pagerdutyconnection.go deleted file mode 100755 index f1acd1d..0000000 --- a/internal/sdk/pkg/models/shared/pagerdutyconnection.go +++ /dev/null @@ -1,11 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type PagerdutyConnection struct { - ClientInfo string `json:"client_info"` - IDToken string `json:"id_token"` - RefreshToken string `json:"refresh_token"` - Scope string `json:"scope"` - TokenType *string `json:"token_type,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/pagerdutyconnectionvalue.go b/internal/sdk/pkg/models/shared/pagerdutyconnectionvalue.go deleted file mode 100755 index b2fb471..0000000 --- a/internal/sdk/pkg/models/shared/pagerdutyconnectionvalue.go +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type PagerdutyConnectionValue struct { - Name *string `json:"name,omitempty"` - Type ConnectionType `json:"type"` - Value PagerdutyConnection `json:"value"` -} diff --git a/internal/sdk/pkg/models/shared/pkcemethod.go b/internal/sdk/pkg/models/shared/pkcemethod.go deleted file mode 100755 index 3422bf4..0000000 --- a/internal/sdk/pkg/models/shared/pkcemethod.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type PkceMethod string - -const ( - PkceMethodS256 PkceMethod = "S256" -) - -func (e PkceMethod) ToPointer() *PkceMethod { - return &e -} - -func (e *PkceMethod) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "S256": - *e = PkceMethod(v) - return nil - default: - return fmt.Errorf("invalid value for PkceMethod: %v", v) - } -} diff --git a/internal/sdk/pkg/models/shared/policy.go b/internal/sdk/pkg/models/shared/policy.go deleted file mode 100755 index 56bb6d8..0000000 --- a/internal/sdk/pkg/models/shared/policy.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type Policy struct { - Bundle *string `json:"bundle,omitempty"` - Query *string `json:"query,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/request.go b/internal/sdk/pkg/models/shared/request.go deleted file mode 100755 index e7841bc..0000000 --- a/internal/sdk/pkg/models/shared/request.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// Request - Created -type Request struct { - CreatedAt time.Time `json:"created_at"` - GrantID string `json:"grant_id"` - GrantKitID string `json:"grant_kit_id"` - GrantKitName *string `json:"grant_kit_name,omitempty"` - GrantKitVersionID string `json:"grant_kit_version_id"` - ID string `json:"id"` - PullRequest string `json:"pull_request"` - Reason string `json:"reason"` - Reviews []Review `json:"reviews,omitempty"` - Status RequestStatus `json:"status"` - UpdatedAt time.Time `json:"updated_at"` - UserID string `json:"user_id"` -} diff --git a/internal/sdk/pkg/models/shared/requestcancelparams.go b/internal/sdk/pkg/models/shared/requestcancelparams.go deleted file mode 100755 index 6085afb..0000000 --- a/internal/sdk/pkg/models/shared/requestcancelparams.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type RequestCancelParams struct { - // The reason for canceling the request - Reason *string `json:"reason,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/requestcontenttype.go b/internal/sdk/pkg/models/shared/requestcontenttype.go deleted file mode 100755 index 1e00e24..0000000 --- a/internal/sdk/pkg/models/shared/requestcontenttype.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type RequestContentType string - -const ( - RequestContentTypeApplicationJSON RequestContentType = "application/json" - RequestContentTypeApplicationXWwwFormUrlencoded RequestContentType = "application/x-www-form-urlencoded" -) - -func (e RequestContentType) ToPointer() *RequestContentType { - return &e -} - -func (e *RequestContentType) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "application/json": - fallthrough - case "application/x-www-form-urlencoded": - *e = RequestContentType(v) - return nil - default: - return fmt.Errorf("invalid value for RequestContentType: %v", v) - } -} diff --git a/internal/sdk/pkg/models/shared/requestparams.go b/internal/sdk/pkg/models/shared/requestparams.go deleted file mode 100755 index 7494bc6..0000000 --- a/internal/sdk/pkg/models/shared/requestparams.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type RequestParams struct { - GrantKitID string `json:"grant_kit_id"` - Reason string `json:"reason"` -} diff --git a/internal/sdk/pkg/models/shared/requestspec.go b/internal/sdk/pkg/models/shared/requestspec.go deleted file mode 100755 index 130dfb2..0000000 --- a/internal/sdk/pkg/models/shared/requestspec.go +++ /dev/null @@ -1,12 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type RequestSpec struct { - // A value conforming to the official JSON Schema core/validation dialect 2020-12 meta-schema. - // - Body interface{} `json:"body,omitempty"` - ContentType *RequestContentType `json:"content_type,omitempty"` - Method HTTPMethod `json:"method"` - URL string `json:"url"` -} diff --git a/internal/sdk/pkg/models/shared/requeststatus.go b/internal/sdk/pkg/models/shared/requeststatus.go deleted file mode 100755 index 3a6b543..0000000 --- a/internal/sdk/pkg/models/shared/requeststatus.go +++ /dev/null @@ -1,41 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type RequestStatus string - -const ( - RequestStatusPending RequestStatus = "Pending" - RequestStatusDenied RequestStatus = "Denied" - RequestStatusApproved RequestStatus = "Approved" - RequestStatusCanceled RequestStatus = "Canceled" -) - -func (e RequestStatus) ToPointer() *RequestStatus { - return &e -} - -func (e *RequestStatus) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "Pending": - fallthrough - case "Denied": - fallthrough - case "Approved": - fallthrough - case "Canceled": - *e = RequestStatus(v) - return nil - default: - return fmt.Errorf("invalid value for RequestStatus: %v", v) - } -} diff --git a/internal/sdk/pkg/models/shared/review.go b/internal/sdk/pkg/models/shared/review.go deleted file mode 100755 index 3f6eb75..0000000 --- a/internal/sdk/pkg/models/shared/review.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "time" -) - -// Review - Success -type Review struct { - CreatedAt time.Time `json:"created_at"` - Grant *Grant `json:"grant,omitempty"` - GrantID string `json:"grant_id"` - GrantKitName string `json:"grant_kit_name"` - GrantKitVersionID string `json:"grant_kit_version_id"` - ID string `json:"id"` - PullRequest string `json:"pull_request"` - Reason string `json:"reason"` - RequestID string `json:"request_id"` - Status ReviewStatus `json:"status"` - UpdatedAt time.Time `json:"updated_at"` - UserEmail *string `json:"user_email,omitempty"` - UserID string `json:"user_id"` -} diff --git a/internal/sdk/pkg/models/shared/reviewers.go b/internal/sdk/pkg/models/shared/reviewers.go deleted file mode 100755 index 2e493d8..0000000 --- a/internal/sdk/pkg/models/shared/reviewers.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type Reviewers struct { - AllOf []string `json:"all_of,omitempty"` - OneOf []string `json:"one_of,omitempty"` -} diff --git a/internal/sdk/pkg/models/shared/reviewstatus.go b/internal/sdk/pkg/models/shared/reviewstatus.go deleted file mode 100755 index b5aef5b..0000000 --- a/internal/sdk/pkg/models/shared/reviewstatus.go +++ /dev/null @@ -1,41 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -import ( - "encoding/json" - "fmt" -) - -type ReviewStatus string - -const ( - ReviewStatusPending ReviewStatus = "Pending" - ReviewStatusDenied ReviewStatus = "Denied" - ReviewStatusApproved ReviewStatus = "Approved" - ReviewStatusCanceled ReviewStatus = "Canceled" -) - -func (e ReviewStatus) ToPointer() *ReviewStatus { - return &e -} - -func (e *ReviewStatus) UnmarshalJSON(data []byte) error { - var v string - if err := json.Unmarshal(data, &v); err != nil { - return err - } - switch v { - case "Pending": - fallthrough - case "Denied": - fallthrough - case "Approved": - fallthrough - case "Canceled": - *e = ReviewStatus(v) - return nil - default: - return fmt.Errorf("invalid value for ReviewStatus: %v", v) - } -} diff --git a/internal/sdk/pkg/models/shared/reviewupdateparams.go b/internal/sdk/pkg/models/shared/reviewupdateparams.go deleted file mode 100755 index fba52ff..0000000 --- a/internal/sdk/pkg/models/shared/reviewupdateparams.go +++ /dev/null @@ -1,7 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type ReviewUpdateParams struct { - Reason string `json:"reason"` -} diff --git a/internal/sdk/pkg/models/shared/security.go b/internal/sdk/pkg/models/shared/security.go deleted file mode 100755 index f069c30..0000000 --- a/internal/sdk/pkg/models/shared/security.go +++ /dev/null @@ -1,7 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type Security struct { - BearerAuth string `security:"scheme,type=http,subtype=bearer,name=Authorization"` -} diff --git a/internal/sdk/pkg/models/shared/step.go b/internal/sdk/pkg/models/shared/step.go deleted file mode 100755 index c21ed97..0000000 --- a/internal/sdk/pkg/models/shared/step.go +++ /dev/null @@ -1,8 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package shared - -type Step struct { - Reviewers *Reviewers `json:"reviewers,omitempty"` - SkipIf []Policy `json:"skip_if,omitempty"` -} diff --git a/internal/sdk/pkg/types/bigint.go b/internal/sdk/pkg/types/bigint.go deleted file mode 100755 index b37a415..0000000 --- a/internal/sdk/pkg/types/bigint.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package types - -import ( - "fmt" - "math/big" -) - -type BigInt struct { - big.Int -} - -func (b BigInt) MarshalJSON() ([]byte, error) { - return []byte(`"` + b.String() + `"`), nil -} - -func (b *BigInt) UnmarshalJSON(p []byte) error { - if string(p) == "null" { - return nil - } - - stringVal := string(p) - if len(stringVal) > 2 && stringVal[0] == '"' && stringVal[len(stringVal)-1] == '"' { - stringVal = stringVal[1 : len(stringVal)-1] - } - - var z big.Int - _, ok := z.SetString(string(stringVal), 10) - if !ok { - return fmt.Errorf("not a valid big integer: %s", p) - } - b.Int = z - return nil -} - -// MustBigIntFromString provides a helper function to return a big.Int from a string -// The string is assumed to be base 10 and if it is not a valid big.Int -// then the function will return nil -func MustBigIntFromString(s string) *BigInt { - i, ok := new(big.Int).SetString(s, 10) - if !ok { - return nil - } - return &BigInt{ - Int: *i, - } -} diff --git a/internal/sdk/pkg/types/date.go b/internal/sdk/pkg/types/date.go deleted file mode 100755 index 01c69b7..0000000 --- a/internal/sdk/pkg/types/date.go +++ /dev/null @@ -1,86 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package types - -import ( - "encoding/json" - "fmt" - "strings" - "time" -) - -// Date is a wrapper around time.Time that allows for JSON marshaling a date string formatted as "2006-01-02". -type Date struct { - time.Time -} - -var ( - _ json.Marshaler = &Date{} - _ json.Unmarshaler = &Date{} - _ fmt.Stringer = &Date{} -) - -// NewDate returns an instance of Date from a time.Time. -func NewDate(t time.Time) *Date { - d := DateFromTime(t) - return &d -} - -// DateFromTime returns a Date from a time.Time. -func DateFromTime(t time.Time) Date { - return Date{t} -} - -// NewDateFromString returns an instance of Date from a string formatted as "2006-01-02". -func NewDateFromString(str string) (*Date, error) { - d, err := DateFromString(str) - if err != nil { - return nil, err - } - - return &d, nil -} - -// DateFromString returns a Date from a string formatted as "2006-01-02". -func DateFromString(str string) (Date, error) { - var d Date - var err error - - d.Time, err = time.Parse("2006-01-02", str) - return d, err -} - -// MustNewDateFromString returns an instance of Date from a string formatted as "2006-01-02" or panics. -// Avoid using this function in production code. -func MustNewDateFromString(str string) *Date { - d := MustDateFromString(str) - return &d -} - -// MustDateFromString returns a Date from a string formatted as "2006-01-02" or panics. -// Avoid using this function in production code. -func MustDateFromString(str string) Date { - d, err := DateFromString(str) - if err != nil { - panic(err) - } - return d -} - -func (d Date) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf(`"%s"`, d.Time.Format("2006-01-02"))), nil -} - -func (d *Date) UnmarshalJSON(data []byte) error { - var err error - - str := string(data) - str = strings.Trim(str, `"`) - - d.Time, err = time.Parse("2006-01-02", str) - return err -} - -func (d Date) String() string { - return d.Time.Format("2006-01-02") -} diff --git a/internal/sdk/pkg/types/datetime.go b/internal/sdk/pkg/types/datetime.go deleted file mode 100755 index 0529b25..0000000 --- a/internal/sdk/pkg/types/datetime.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package types - -import "time" - -// MustTimeFromString returns a time.Time from a string formatted as "2006-01-02T15:04:05Z07:00" or panics. -// Avoid using this function in production code. -func MustTimeFromString(str string) time.Time { - t, err := time.Parse(time.RFC3339, str) - if err != nil { - panic(err) - } - - return t -} - -// MustNewTimeFromString returns an instance of time.Time from a string formatted as "2006-01-02T15:04:05Z07:00" or panics. -// Avoid using this function in production code. -func MustNewTimeFromString(str string) *time.Time { - t := MustTimeFromString(str) - return &t -} diff --git a/internal/sdk/pkg/utils/contenttype.go b/internal/sdk/pkg/utils/contenttype.go deleted file mode 100755 index 8ed13e2..0000000 --- a/internal/sdk/pkg/utils/contenttype.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "fmt" - "mime" - "strings" -) - -func MatchContentType(contentType string, pattern string) bool { - if contentType == pattern || pattern == "*" || pattern == "*/*" { - return true - } - - mediaType, _, err := mime.ParseMediaType(contentType) - if err != nil { - return false - } - - if mediaType == pattern { - return true - } - - parts := strings.Split(mediaType, "/") - if len(parts) == 2 { - if fmt.Sprintf("%s/*", parts[0]) == pattern || fmt.Sprintf("*/%s", parts[1]) == pattern { - return true - } - } - - return false -} diff --git a/internal/sdk/pkg/utils/form.go b/internal/sdk/pkg/utils/form.go deleted file mode 100755 index 5e12f27..0000000 --- a/internal/sdk/pkg/utils/form.go +++ /dev/null @@ -1,114 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "fmt" - "math/big" - "net/url" - "reflect" - "strings" - "time" - - "abbey/v2/internal/sdk/pkg/types" -) - -func populateForm(paramName string, explode bool, objType reflect.Type, objValue reflect.Value, delimiter string, getFieldName func(reflect.StructField) string) url.Values { - - formValues := url.Values{} - - if objType.Kind() == reflect.Pointer { - if objValue.IsNil() { - return formValues - } - objType = objType.Elem() - objValue = objValue.Elem() - } - - switch objType.Kind() { - case reflect.Struct: - switch objValue.Interface().(type) { - case time.Time: - formValues.Add(paramName, valToString(objValue.Interface())) - case types.Date: - formValues.Add(paramName, valToString(objValue.Interface())) - case types.BigInt: - formValues.Add(paramName, valToString(objValue.Interface())) - case big.Int: - formValues.Add(paramName, valToString(objValue.Interface())) - default: - var items []string - - for i := 0; i < objType.NumField(); i++ { - fieldType := objType.Field(i) - valType := objValue.Field(i) - - if valType.Kind() == reflect.Pointer { - if valType.IsNil() { - continue - } - - valType = valType.Elem() - } - - fieldName := getFieldName(fieldType) - if fieldName == "" { - continue - } - - if explode { - formValues.Add(fieldName, valToString(valType.Interface())) - } else { - items = append(items, fmt.Sprintf("%s%s%s", fieldName, delimiter, valToString(valType.Interface()))) - } - } - - if len(items) > 0 { - formValues.Add(paramName, strings.Join(items, delimiter)) - } - } - case reflect.Map: - items := []string{} - - iter := objValue.MapRange() - for iter.Next() { - if explode { - formValues.Add(iter.Key().String(), valToString(iter.Value().Interface())) - } else { - items = append(items, fmt.Sprintf("%s%s%s", iter.Key().String(), delimiter, valToString(iter.Value().Interface()))) - } - } - - if len(items) > 0 { - formValues.Add(paramName, strings.Join(items, delimiter)) - } - case reflect.Slice, reflect.Array: - values := parseDelimitedArray(explode, objValue, delimiter) - for _, v := range values { - formValues.Add(paramName, v) - } - default: - formValues.Add(paramName, valToString(objValue.Interface())) - } - - return formValues -} - -func parseDelimitedArray(explode bool, objValue reflect.Value, delimiter string) []string { - values := []string{} - items := []string{} - - for i := 0; i < objValue.Len(); i++ { - if explode { - values = append(values, valToString(objValue.Index(i).Interface())) - } else { - items = append(items, valToString(objValue.Index(i).Interface())) - } - } - - if len(items) > 0 { - values = append(values, strings.Join(items, delimiter)) - } - - return values -} diff --git a/internal/sdk/pkg/utils/headers.go b/internal/sdk/pkg/utils/headers.go deleted file mode 100755 index d8ca9b1..0000000 --- a/internal/sdk/pkg/utils/headers.go +++ /dev/null @@ -1,100 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "context" - "fmt" - "net/http" - "reflect" - "strings" -) - -func PopulateHeaders(ctx context.Context, req *http.Request, headers interface{}) { - headerParamsStructType := reflect.TypeOf(headers) - headerParamsValType := reflect.ValueOf(headers) - - for i := 0; i < headerParamsStructType.NumField(); i++ { - fieldType := headerParamsStructType.Field(i) - valType := headerParamsValType.Field(i) - - tag := parseParamTag(headerParamTagKey, fieldType, "simple", false) - if tag == nil { - continue - } - - value := serializeHeader(fieldType.Type, valType, tag.Explode) - if value != "" { - req.Header.Add(tag.ParamName, value) - } - } -} - -func serializeHeader(objType reflect.Type, objValue reflect.Value, explode bool) string { - if objType.Kind() == reflect.Pointer { - if objValue.IsNil() { - return "" - } - objType = objType.Elem() - objValue = objValue.Elem() - } - - switch objType.Kind() { - case reflect.Struct: - items := []string{} - - for i := 0; i < objType.NumField(); i++ { - fieldType := objType.Field(i) - valType := objValue.Field(i) - - if fieldType.Type.Kind() == reflect.Pointer { - if valType.IsNil() { - continue - } - valType = valType.Elem() - } - - tag := parseParamTag(headerParamTagKey, fieldType, "simple", false) - if tag == nil { - continue - } - - fieldName := tag.ParamName - - if fieldName == "" { - continue - } - - if explode { - items = append(items, fmt.Sprintf("%s=%s", fieldName, valToString(valType.Interface()))) - } else { - items = append(items, fieldName, valToString(valType.Interface())) - } - } - - return strings.Join(items, ",") - case reflect.Map: - items := []string{} - - iter := objValue.MapRange() - for iter.Next() { - if explode { - items = append(items, fmt.Sprintf("%s=%s", iter.Key().String(), valToString(iter.Value().Interface()))) - } else { - items = append(items, iter.Key().String(), valToString(iter.Value().Interface())) - } - } - - return strings.Join(items, ",") - case reflect.Slice, reflect.Array: - items := []string{} - - for i := 0; i < objValue.Len(); i++ { - items = append(items, valToString(objValue.Index(i).Interface())) - } - - return strings.Join(items, ",") - default: - return valToString(objValue.Interface()) - } -} diff --git a/internal/sdk/pkg/utils/pathparams.go b/internal/sdk/pkg/utils/pathparams.go deleted file mode 100755 index c2fd728..0000000 --- a/internal/sdk/pkg/utils/pathparams.go +++ /dev/null @@ -1,126 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "context" - "fmt" - "net/url" - "reflect" - "strings" -) - -func GenerateURL(ctx context.Context, serverURL, path string, pathParams interface{}, globals map[string]map[string]map[string]interface{}) (string, error) { - uri := strings.TrimSuffix(serverURL, "/") + path - - pathParamsStructType := reflect.TypeOf(pathParams) - pathParamsValType := reflect.ValueOf(pathParams) - - parsedParameters := map[string]string{} - - for i := 0; i < pathParamsStructType.NumField(); i++ { - fieldType := pathParamsStructType.Field(i) - valType := pathParamsValType.Field(i) - - requestTag := getRequestTag(fieldType) - if requestTag != nil { - continue - } - - ppTag := parseParamTag(pathParamTagKey, fieldType, "simple", false) - if ppTag == nil { - continue - } - - valType = populateFromGlobals(fieldType, valType, "pathParam", globals) - - if ppTag.Serialization != "" { - vals, err := populateSerializedParams(ppTag, fieldType.Type, valType) - if err != nil { - return "", err - } - for k, v := range vals { - parsedParameters[k] = url.PathEscape(v) - } - } else { - // TODO: support other styles - switch ppTag.Style { - case "simple": - simpleParams := getSimplePathParams(ctx, ppTag.ParamName, fieldType.Type, valType, ppTag.Explode) - for k, v := range simpleParams { - parsedParameters[k] = v - } - } - } - } - - // TODO should we handle the case where there are no matching path params? - return ReplaceParameters(uri, parsedParameters), nil -} - -func getSimplePathParams(ctx context.Context, parentName string, objType reflect.Type, objValue reflect.Value, explode bool) map[string]string { - pathParams := make(map[string]string) - - if objType.Kind() == reflect.Ptr { - if objValue.IsNil() { - return nil - } - objType = objType.Elem() - objValue = objValue.Elem() - } - - switch objType.Kind() { - case reflect.Array, reflect.Slice: - if objValue.Len() == 0 { - return nil - } - var ppVals []string - for i := 0; i < objValue.Len(); i++ { - ppVals = append(ppVals, valToString(objValue.Index(i).Interface())) - } - pathParams[parentName] = strings.Join(ppVals, ",") - case reflect.Map: - if objValue.Len() == 0 { - return nil - } - var ppVals []string - objMap := objValue.MapRange() - for objMap.Next() { - if explode { - ppVals = append(ppVals, fmt.Sprintf("%s=%s", objMap.Key().String(), valToString(objMap.Value().Interface()))) - } else { - ppVals = append(ppVals, fmt.Sprintf("%s,%s", objMap.Key().String(), valToString(objMap.Value().Interface()))) - } - } - pathParams[parentName] = strings.Join(ppVals, ",") - case reflect.Struct: - var ppVals []string - for i := 0; i < objType.NumField(); i++ { - fieldType := objType.Field(i) - valType := objValue.Field(i) - - ppTag := parseParamTag(pathParamTagKey, fieldType, "simple", explode) - if ppTag == nil { - continue - } - - if fieldType.Type.Kind() == reflect.Pointer { - if valType.IsNil() { - continue - } - valType = valType.Elem() - } - - if explode { - ppVals = append(ppVals, fmt.Sprintf("%s=%s", ppTag.ParamName, valToString(valType.Interface()))) - } else { - ppVals = append(ppVals, fmt.Sprintf("%s,%s", ppTag.ParamName, valToString(valType.Interface()))) - } - } - pathParams[parentName] = strings.Join(ppVals, ",") - default: - pathParams[parentName] = valToString(objValue.Interface()) - } - - return pathParams -} diff --git a/internal/sdk/pkg/utils/queryparams.go b/internal/sdk/pkg/utils/queryparams.go deleted file mode 100755 index 87ecef8..0000000 --- a/internal/sdk/pkg/utils/queryparams.go +++ /dev/null @@ -1,178 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/url" - "reflect" -) - -func PopulateQueryParams(ctx context.Context, req *http.Request, queryParams interface{}, globals map[string]map[string]map[string]interface{}) error { - queryParamsStructType := reflect.TypeOf(queryParams) - queryParamsValType := reflect.ValueOf(queryParams) - - values := url.Values{} - - for i := 0; i < queryParamsStructType.NumField(); i++ { - fieldType := queryParamsStructType.Field(i) - valType := queryParamsValType.Field(i) - - requestTag := getRequestTag(fieldType) - if requestTag != nil { - continue - } - - qpTag := parseQueryParamTag(fieldType) - if qpTag == nil { - continue - } - - valType = populateFromGlobals(fieldType, valType, "queryParam", globals) - - if qpTag.Serialization != "" { - vals, err := populateSerializedParams(qpTag, fieldType.Type, valType) - if err != nil { - return err - } - for k, v := range vals { - values.Add(k, v) - } - } else { - switch qpTag.Style { - case "deepObject": - vals := populateDeepObjectParams(req, qpTag, fieldType.Type, valType) - for k, v := range vals { - for _, vv := range v { - values.Add(k, vv) - } - } - case "form": - vals := populateFormParams(req, qpTag, fieldType.Type, valType, ",") - for k, v := range vals { - for _, vv := range v { - values.Add(k, vv) - } - } - case "pipeDelimited": - vals := populateFormParams(req, qpTag, fieldType.Type, valType, "|") - for k, v := range vals { - for _, vv := range v { - values.Add(k, vv) - } - } - default: - return fmt.Errorf("unsupported style: %s", qpTag.Style) - } - } - } - - req.URL.RawQuery = values.Encode() - - return nil -} - -func populateSerializedParams(tag *paramTag, objType reflect.Type, objValue reflect.Value) (map[string]string, error) { - if objType.Kind() == reflect.Pointer { - if objValue.IsNil() { - return nil, nil - } - objValue = objValue.Elem() - } - if objValue.Interface() == nil { - return nil, nil - } - - values := map[string]string{} - - switch tag.Serialization { - case "json": - data, err := json.Marshal(objValue.Interface()) - if err != nil { - return nil, fmt.Errorf("error marshaling json: %v", err) - } - values[tag.ParamName] = string(data) - } - - return values, nil -} - -func populateDeepObjectParams(req *http.Request, tag *paramTag, objType reflect.Type, objValue reflect.Value) url.Values { - values := url.Values{} - - if objType.Kind() == reflect.Pointer { - if objValue.IsNil() { - return values - } - objType = objType.Elem() - objValue = objValue.Elem() - } - - switch objType.Kind() { - case reflect.Struct: - for i := 0; i < objType.NumField(); i++ { - fieldType := objType.Field(i) - valType := objValue.Field(i) - - if fieldType.Type.Kind() == reflect.Pointer { - if valType.IsNil() { - continue - } - valType = valType.Elem() - } - - qpTag := parseQueryParamTag(fieldType) - if qpTag == nil { - continue - } - - switch valType.Kind() { - case reflect.Array, reflect.Slice: - for i := 0; i < valType.Len(); i++ { - values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, qpTag.ParamName), valToString(valType.Index(i).Interface())) - } - default: - values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, qpTag.ParamName), valToString(valType.Interface())) - } - } - case reflect.Map: - iter := objValue.MapRange() - for iter.Next() { - switch iter.Value().Kind() { - case reflect.Array, reflect.Slice: - for i := 0; i < iter.Value().Len(); i++ { - values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, iter.Key().String()), valToString(iter.Value().Index(i).Interface())) - } - default: - values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, iter.Key().String()), valToString(iter.Value().Interface())) - } - } - } - - return values -} - -func populateFormParams(req *http.Request, tag *paramTag, objType reflect.Type, objValue reflect.Value, delimiter string) url.Values { - return populateForm(tag.ParamName, tag.Explode, objType, objValue, delimiter, func(fieldType reflect.StructField) string { - qpTag := parseQueryParamTag(fieldType) - if qpTag == nil { - return "" - } - - return qpTag.ParamName - }) -} - -type paramTag struct { - Style string - Explode bool - ParamName string - Serialization string -} - -func parseQueryParamTag(field reflect.StructField) *paramTag { - return parseParamTag(queryParamTagKey, field, "form", true) -} diff --git a/internal/sdk/pkg/utils/requestbody.go b/internal/sdk/pkg/utils/requestbody.go deleted file mode 100755 index 5c1d263..0000000 --- a/internal/sdk/pkg/utils/requestbody.go +++ /dev/null @@ -1,373 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "mime/multipart" - "net/url" - "reflect" - "regexp" -) - -const ( - requestTagKey = "request" - multipartFormTagKey = "multipartForm" - formTagKey = "form" -) - -var ( - jsonEncodingRegex = regexp.MustCompile(`(application|text)\/.*?\+*json.*`) - multipartEncodingRegex = regexp.MustCompile(`multipart\/.*`) - urlEncodedEncodingRegex = regexp.MustCompile(`application\/x-www-form-urlencoded.*`) -) - -func SerializeRequestBody(ctx context.Context, request interface{}, requestFieldName string, serializationMethod string) (*bytes.Buffer, string, error) { - requestStructType := reflect.TypeOf(request) - requestValType := reflect.ValueOf(request) - - if requestStructType.Kind() == reflect.Pointer { - if requestValType.IsNil() { - return nil, "", nil - } - - requestStructType = requestStructType.Elem() - requestValType = requestValType.Elem() - } - - if requestStructType.Kind() != reflect.Struct { - return serializeContentType(requestFieldName, SerializationMethodToContentType[serializationMethod], requestValType) - } - - requestField, ok := requestStructType.FieldByName(requestFieldName) - - if ok { - tag := getRequestTag(requestField) - if tag != nil { - // request object (non-flattened) - requestVal := requestValType.FieldByName(requestFieldName) - if requestField.Type.Kind() == reflect.Pointer && requestVal.IsNil() { - return nil, "", nil - } - - return serializeContentType(requestFieldName, tag.MediaType, requestVal) - } - } - - // flattened request object - return serializeContentType(requestFieldName, SerializationMethodToContentType[serializationMethod], requestValType) -} - -func serializeContentType(fieldName string, mediaType string, val reflect.Value) (*bytes.Buffer, string, error) { - buf := &bytes.Buffer{} - - switch { - case jsonEncodingRegex.MatchString(mediaType): - if err := json.NewEncoder(buf).Encode(val.Interface()); err != nil { - return nil, "", err - } - case multipartEncodingRegex.MatchString(mediaType): - var err error - mediaType, err = encodeMultipartFormData(buf, val.Interface()) - if err != nil { - return nil, "", err - } - case urlEncodedEncodingRegex.MatchString(mediaType): - if err := encodeFormData(fieldName, buf, val.Interface()); err != nil { - return nil, "", err - } - default: - val = reflect.Indirect(val) - - switch { - case val.Type().Kind() == reflect.String: - if _, err := buf.WriteString(valToString(val.Interface())); err != nil { - return nil, "", err - } - case val.Type() == reflect.TypeOf([]byte(nil)): - if _, err := buf.Write(val.Bytes()); err != nil { - return nil, "", err - } - default: - return nil, "", fmt.Errorf("invalid request body type %s for mediaType %s", val.Type(), mediaType) - } - } - - return buf, mediaType, nil -} - -func encodeMultipartFormData(w io.Writer, data interface{}) (string, error) { - requestStructType := reflect.TypeOf(data) - requestValType := reflect.ValueOf(data) - - if requestStructType.Kind() == reflect.Pointer { - requestStructType = requestStructType.Elem() - requestValType = requestValType.Elem() - } - - writer := multipart.NewWriter(w) - - for i := 0; i < requestStructType.NumField(); i++ { - field := requestStructType.Field(i) - fieldType := field.Type - valType := requestValType.Field(i) - - if fieldType.Kind() == reflect.Pointer { - if valType.IsNil() { - continue - } - - fieldType = fieldType.Elem() - valType = valType.Elem() - } - - tag := parseMultipartFormTag(field) - if tag.File { - if err := encodeMultipartFormDataFile(writer, fieldType, valType); err != nil { - writer.Close() - return "", err - } - } else if tag.JSON { - jw, err := writer.CreateFormField(tag.Name) - if err != nil { - writer.Close() - return "", err - } - d, err := json.Marshal(valType.Interface()) - if err != nil { - writer.Close() - return "", err - } - if _, err := jw.Write(d); err != nil { - writer.Close() - return "", err - } - } else { - switch fieldType.Kind() { - case reflect.Slice, reflect.Array: - values := parseDelimitedArray(true, valType, ",") - for _, v := range values { - if err := writer.WriteField(tag.Name+"[]", v); err != nil { - writer.Close() - return "", err - } - } - default: - if err := writer.WriteField(tag.Name, valToString(valType.Interface())); err != nil { - writer.Close() - return "", err - } - } - } - } - - if err := writer.Close(); err != nil { - return "", err - } - - return writer.FormDataContentType(), nil -} - -func encodeMultipartFormDataFile(w *multipart.Writer, fieldType reflect.Type, valType reflect.Value) error { - if fieldType.Kind() != reflect.Struct { - return fmt.Errorf("invalid type %s for multipart/form-data file", valType.Type()) - } - - var fieldName string - var fileName string - var content []byte - - for i := 0; i < fieldType.NumField(); i++ { - field := fieldType.Field(i) - val := valType.Field(i) - - tag := parseMultipartFormTag(field) - if !tag.Content && tag.Name == "" { - continue - } - - if tag.Content { - content = val.Bytes() - } else { - fieldName = tag.Name - fileName = val.String() - } - } - - if fieldName == "" || fileName == "" || content == nil { - return fmt.Errorf("invalid multipart/form-data file") - } - - fw, err := w.CreateFormFile(fieldName, fileName) - if err != nil { - return err - } - if _, err := fw.Write(content); err != nil { - return err - } - - return nil -} - -func encodeFormData(fieldName string, w io.Writer, data interface{}) error { - requestType := reflect.TypeOf(data) - requestValType := reflect.ValueOf(data) - - if requestType.Kind() == reflect.Pointer { - requestType = requestType.Elem() - requestValType = requestValType.Elem() - } - - dataValues := url.Values{} - - switch requestType.Kind() { - case reflect.Struct: - for i := 0; i < requestType.NumField(); i++ { - field := requestType.Field(i) - fieldType := field.Type - valType := requestValType.Field(i) - - if fieldType.Kind() == reflect.Pointer { - if valType.IsNil() { - continue - } - - fieldType = fieldType.Elem() - valType = valType.Elem() - } - - tag := parseFormTag(field) - if tag.JSON { - data, err := json.Marshal(valType.Interface()) - if err != nil { - return err - } - dataValues.Set(tag.Name, string(data)) - } else { - switch tag.Style { - // TODO: support other styles - case "form": - values := populateForm(tag.Name, tag.Explode, fieldType, valType, ",", func(sf reflect.StructField) string { - tag := parseFormTag(field) - if tag == nil { - return "" - } - - return tag.Name - }) - for k, v := range values { - for _, vv := range v { - dataValues.Add(k, vv) - } - } - } - } - } - case reflect.Map: - for _, k := range requestValType.MapKeys() { - v := requestValType.MapIndex(k) - dataValues.Set(fmt.Sprintf("%v", k.Interface()), valToString(v.Interface())) - } - case reflect.Slice, reflect.Array: - for i := 0; i < requestValType.Len(); i++ { - v := requestValType.Index(i) - dataValues.Set(fieldName, valToString(v.Interface())) - } - } - - if _, err := w.Write([]byte(dataValues.Encode())); err != nil { - return err - } - - return nil -} - -type requestTag struct { - MediaType string -} - -func getRequestTag(field reflect.StructField) *requestTag { - // example `request:"mediaType=multipart/form-data"` - values := parseStructTag(requestTagKey, field) - if values == nil { - return nil - } - - tag := &requestTag{ - MediaType: "application/octet-stream", - } - - for k, v := range values { - switch k { - case "mediaType": - tag.MediaType = v - } - } - - return tag -} - -type multipartFormTag struct { - File bool - Content bool - JSON bool - Name string -} - -func parseMultipartFormTag(field reflect.StructField) *multipartFormTag { - // example `multipartForm:"name=file"` - values := parseStructTag(multipartFormTagKey, field) - - tag := &multipartFormTag{} - - for k, v := range values { - switch k { - case "file": - tag.File = v == "true" - case "content": - tag.Content = v == "true" - case "name": - tag.Name = v - case "json": - tag.JSON = v == "true" - } - } - - return tag -} - -type formTag struct { - Name string - JSON bool - Style string - Explode bool -} - -func parseFormTag(field reflect.StructField) *formTag { - // example `form:"name=propName,style=spaceDelimited,explode"` - values := parseStructTag(formTagKey, field) - - tag := &formTag{ - Style: "form", - Explode: true, - } - - for k, v := range values { - switch k { - case "name": - tag.Name = v - case "json": - tag.JSON = v == "true" - case "style": - tag.Style = v - case "explode": - tag.Explode = v == "true" - } - } - - return tag -} diff --git a/internal/sdk/pkg/utils/retries.go b/internal/sdk/pkg/utils/retries.go deleted file mode 100755 index ff39d0d..0000000 --- a/internal/sdk/pkg/utils/retries.go +++ /dev/null @@ -1,117 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "context" - "errors" - "fmt" - "net/http" - "net/url" - "strconv" - "strings" - "time" - - "github.com/cenkalti/backoff/v4" -) - -var errRequestFailed = errors.New("request failed") - -type BackoffStrategy struct { - InitialInterval int - MaxInterval int - Exponent float64 - MaxElapsedTime int -} - -type RetryConfig struct { - Strategy string - Backoff *BackoffStrategy - RetryConnectionErrors bool -} - -type Retries struct { - Config *RetryConfig - StatusCodes []string -} - -func Retry(ctx context.Context, r Retries, action func() (*http.Response, error)) (*http.Response, error) { - switch r.Config.Strategy { - case "backoff": - if r.Config.Backoff == nil { - return action() - } - - config := backoff.NewExponentialBackOff() - config.InitialInterval = time.Duration(r.Config.Backoff.InitialInterval) * time.Millisecond - config.MaxInterval = time.Duration(r.Config.Backoff.MaxInterval) * time.Millisecond - config.Multiplier = r.Config.Backoff.Exponent - config.MaxElapsedTime = time.Duration(r.Config.Backoff.MaxElapsedTime) * time.Millisecond - config.Reset() - - var resp *http.Response - - err := backoff.Retry(func() error { - if resp != nil { - resp.Body.Close() - } - - select { - case <-ctx.Done(): - return backoff.Permanent(ctx.Err()) - default: - } - - res, err := action() - if err != nil { - urlError := new(url.Error) - if errors.As(err, &urlError) { - if (urlError.Temporary() || urlError.Timeout()) && r.Config.RetryConnectionErrors { - return err - } - } - - return backoff.Permanent(err) - } - resp = res - if res == nil { - return fmt.Errorf("no response") - } - - for _, code := range r.StatusCodes { - if strings.Contains(strings.ToUpper(code), "X") { - codeRange, err := strconv.Atoi(code[:1]) - if err != nil { - continue - } - - s := res.StatusCode / 100 - - if s >= codeRange && s < codeRange+1 { - return errRequestFailed - } - } else { - parsedCode, err := strconv.Atoi(code) - if err != nil { - continue - } - - if res.StatusCode == parsedCode { - return errRequestFailed - } - } - } - - resp = res - - return nil - }, config) - if err != nil && !errors.Is(err, errRequestFailed) { - return nil, err - } - - return resp, nil - default: - return action() - } -} diff --git a/internal/sdk/pkg/utils/security.go b/internal/sdk/pkg/utils/security.go deleted file mode 100755 index ec837d7..0000000 --- a/internal/sdk/pkg/utils/security.go +++ /dev/null @@ -1,292 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "encoding/base64" - "fmt" - "net/http" - "reflect" - "strings" -) - -type HTTPClient interface { - Do(req *http.Request) (*http.Response, error) -} - -const ( - securityTagKey = "security" -) - -type securityTag struct { - Option bool - Scheme bool - Name string - Type string - SubType string -} - -type SecurityClient struct { - client HTTPClient - headers map[string]string - queryParams map[string]string -} - -func newSecurityClient(client HTTPClient) *SecurityClient { - return &SecurityClient{ - client: client, - headers: make(map[string]string), - queryParams: make(map[string]string), - } -} - -func (c *SecurityClient) Do(req *http.Request) (*http.Response, error) { - for k, v := range c.headers { - req.Header.Set(k, v) - } - - queryParams := req.URL.Query() - - for k, v := range c.queryParams { - queryParams.Set(k, v) - } - - req.URL.RawQuery = queryParams.Encode() - - return c.client.Do(req) -} - -func ConfigureSecurityClient(c HTTPClient, security interface{}) *SecurityClient { - client := parseSecurityStruct(c, security) - if client != nil { - return client - } - - return newSecurityClient(c) -} - -func parseSecurityStruct(c HTTPClient, security interface{}) *SecurityClient { - securityStructType := reflect.TypeOf(security) - securityValType := reflect.ValueOf(security) - - if securityStructType.Kind() == reflect.Ptr { - if securityValType.IsNil() { - return nil - } - - securityStructType = securityStructType.Elem() - securityValType = securityValType.Elem() - } - - client := newSecurityClient(c) - - for i := 0; i < securityStructType.NumField(); i++ { - fieldType := securityStructType.Field(i) - valType := securityValType.Field(i) - - kind := valType.Kind() - - if fieldType.Type.Kind() == reflect.Pointer { - if valType.IsNil() { - continue - } - - kind = valType.Elem().Kind() - } - - secTag := parseSecurityTag(fieldType) - if secTag != nil { - if secTag.Option { - return parseSecurityOption(c, valType.Interface()) - } else if secTag.Scheme { - // Special case for basic auth which could be a flattened struct - if secTag.SubType == "basic" && kind != reflect.Struct { - parseSecurityScheme(client, secTag, security) - return client - } else { - parseSecurityScheme(client, secTag, valType.Interface()) - } - } - } - } - - return client -} - -func parseSecurityOption(c HTTPClient, option interface{}) *SecurityClient { - optionStructType := reflect.TypeOf(option) - optionValType := reflect.ValueOf(option) - - if optionStructType.Kind() == reflect.Ptr { - if optionValType.IsNil() { - return nil - } - - optionStructType = optionStructType.Elem() - optionValType = optionValType.Elem() - } - - client := newSecurityClient(c) - - for i := 0; i < optionStructType.NumField(); i++ { - fieldType := optionStructType.Field(i) - valType := optionValType.Field(i) - - secTag := parseSecurityTag(fieldType) - if secTag != nil && secTag.Scheme { - parseSecurityScheme(client, secTag, valType.Interface()) - } - } - - return client -} - -func parseSecurityScheme(client *SecurityClient, schemeTag *securityTag, scheme interface{}) { - schemeType := reflect.TypeOf(scheme) - schemeVal := reflect.ValueOf(scheme) - - if schemeType.Kind() == reflect.Ptr { - if schemeVal.IsNil() { - return - } - - schemeType = schemeType.Elem() - schemeVal = schemeVal.Elem() - } - - if schemeType.Kind() == reflect.Struct { - if schemeTag.Type == "http" && schemeTag.SubType == "basic" { - parseBasicAuthScheme(client, schemeVal.Interface()) - return - } - - for i := 0; i < schemeType.NumField(); i++ { - fieldType := schemeType.Field(i) - valType := schemeVal.Field(i) - - if fieldType.Type.Kind() == reflect.Ptr { - if valType.IsNil() { - continue - } - - valType = valType.Elem() - } - - secTag := parseSecurityTag(fieldType) - if secTag == nil || secTag.Name == "" { - return - } - - parseSecuritySchemeValue(client, schemeTag, secTag, valType.Interface()) - } - } else { - parseSecuritySchemeValue(client, schemeTag, schemeTag, schemeVal.Interface()) - } -} - -func parseSecuritySchemeValue(client *SecurityClient, schemeTag *securityTag, secTag *securityTag, val interface{}) { - switch schemeTag.Type { - case "apiKey": - switch schemeTag.SubType { - case "header": - client.headers[secTag.Name] = valToString(val) - case "query": - client.queryParams[secTag.Name] = valToString(val) - case "cookie": - client.headers["Cookie"] = fmt.Sprintf("%s=%s", secTag.Name, valToString(val)) - default: - panic("not supported") - } - case "openIdConnect": - client.headers[secTag.Name] = valToString(val) - case "oauth2": - client.headers[secTag.Name] = valToString(val) - case "http": - switch schemeTag.SubType { - case "bearer": - client.headers[secTag.Name] = prefixBearer(valToString(val)) - default: - panic("not supported") - } - default: - panic("not supported") - } -} - -func prefixBearer(authHeaderValue string) string { - if strings.HasPrefix(strings.ToLower(authHeaderValue), "bearer ") { - return authHeaderValue - } - - return fmt.Sprintf("Bearer %s", authHeaderValue) -} - -func parseBasicAuthScheme(client *SecurityClient, scheme interface{}) { - schemeStructType := reflect.TypeOf(scheme) - schemeValType := reflect.ValueOf(scheme) - - var username, password string - - for i := 0; i < schemeStructType.NumField(); i++ { - fieldType := schemeStructType.Field(i) - valType := schemeValType.Field(i) - - secTag := parseSecurityTag(fieldType) - if secTag == nil || secTag.Name == "" { - continue - } - - switch secTag.Name { - case "username": - username = valType.String() - case "password": - password = valType.String() - } - } - - client.headers["Authorization"] = fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password)))) -} - -func parseSecurityTag(field reflect.StructField) *securityTag { - tag := field.Tag.Get(securityTagKey) - if tag == "" { - return nil - } - - option := false - scheme := false - name := "" - securityType := "" - securitySubType := "" - - options := strings.Split(tag, ",") - for _, optionConf := range options { - parts := strings.Split(optionConf, "=") - if len(parts) < 1 || len(parts) > 2 { - continue - } - - switch parts[0] { - case "name": - name = parts[1] - case "type": - securityType = parts[1] - case "subtype": - securitySubType = parts[1] - case "option": - option = true - case "scheme": - scheme = true - } - } - - // TODO: validate tag? - - return &securityTag{ - Option: option, - Scheme: scheme, - Name: name, - Type: securityType, - SubType: securitySubType, - } -} diff --git a/internal/sdk/pkg/utils/utils.go b/internal/sdk/pkg/utils/utils.go deleted file mode 100755 index fc65050..0000000 --- a/internal/sdk/pkg/utils/utils.go +++ /dev/null @@ -1,152 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package utils - -import ( - "encoding/json" - "fmt" - "io" - "math/big" - "reflect" - "regexp" - "strings" - "time" - - "abbey/v2/internal/sdk/pkg/types" -) - -const ( - queryParamTagKey = "queryParam" - headerParamTagKey = "header" - pathParamTagKey = "pathParam" -) - -var ( - paramRegex = regexp.MustCompile(`({.*?})`) - SerializationMethodToContentType = map[string]string{ - "json": "application/json", - "form": "application/x-www-form-urlencoded", - "multipart": "multipart/form-data", - "raw": "application/octet-stream", - "string": "text/plain", - } -) - -func UnmarshalJsonFromResponseBody(body io.Reader, out interface{}) error { - data, err := io.ReadAll(body) - if err != nil { - return fmt.Errorf("error reading response body: %w", err) - } - if err := json.Unmarshal(data, &out); err != nil { - return fmt.Errorf("error unmarshalling json response body: %w", err) - } - - return nil -} - -func ReplaceParameters(stringWithParams string, params map[string]string) string { - return paramRegex.ReplaceAllStringFunc(stringWithParams, func(match string) string { - match = match[1 : len(match)-1] - return params[match] - }) -} - -func Contains(slice []string, item string) bool { - for _, s := range slice { - if s == item { - return true - } - } - return false -} - -func parseStructTag(tagKey string, field reflect.StructField) map[string]string { - tag := field.Tag.Get(tagKey) - if tag == "" { - return nil - } - - values := map[string]string{} - - options := strings.Split(tag, ",") - for _, optionConf := range options { - parts := strings.Split(optionConf, "=") - - switch len(parts) { - case 1: - // flag option - parts = append(parts, "true") - case 2: - // key=value option - break - default: - // invalid option - continue - } - - values[parts[0]] = parts[1] - } - - return values -} - -func parseParamTag(tagKey string, field reflect.StructField, defaultStyle string, defaultExplode bool) *paramTag { - // example `{tagKey}:"style=simple,explode=false,name=apiID"` - values := parseStructTag(tagKey, field) - if values == nil { - return nil - } - - tag := ¶mTag{ - Style: defaultStyle, - Explode: defaultExplode, - ParamName: strings.ToLower(field.Name), - } - - for k, v := range values { - switch k { - case "style": - tag.Style = v - case "explode": - tag.Explode = v == "true" - case "name": - tag.ParamName = v - case "serialization": - tag.Serialization = v - } - } - - return tag -} - -func valToString(val interface{}) string { - switch v := val.(type) { - case time.Time: - return v.Format(time.RFC3339Nano) - case types.BigInt: - return v.String() - case big.Int: - return v.String() - default: - return fmt.Sprintf("%v", v) - } -} - -func populateFromGlobals(fieldType reflect.StructField, valType reflect.Value, paramType string, globals map[string]map[string]map[string]interface{}) reflect.Value { - if globals != nil && fieldType.Type.Kind() == reflect.Ptr { - parameters, ok := globals["parameters"] - if ok { - paramsOfType, ok := parameters[paramType] - if ok { - globalVal, ok := paramsOfType[fieldType.Name] - if ok { - if reflect.TypeOf(globalVal).Kind() == fieldType.Type.Elem().Kind() && valType.IsNil() { - valType = reflect.ValueOf(&globalVal) - } - } - } - } - } - - return valType -} diff --git a/internal/sdk/requests.go b/internal/sdk/requests.go deleted file mode 100755 index b5509e8..0000000 --- a/internal/sdk/requests.go +++ /dev/null @@ -1,342 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// requests - Requests are Access Requests that users make to get access to a resource. -// -// https://docs.abbey.io/getting-started/concepts#access-requests -type requests struct { - sdkConfiguration sdkConfiguration -} - -func newRequests(sdkConfig sdkConfiguration) *requests { - return &requests{ - sdkConfiguration: sdkConfig, - } -} - -// CancelRequestByID - Cancel a Request by ID -// Cancels the specified request. -func (s *requests) CancelRequestByID(ctx context.Context, request operations.CancelRequestByIDRequest) (*operations.CancelRequestByIDResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/requests/{request_id}/cancel", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "RequestCancelParams", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "PUT", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.CancelRequestByIDResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Request - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Request = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// CreateRequest - Create a Request -// Creates a new request. -// -// You will need to pass in a Grant Kit ID as the target of this request. This will create a request -// against the latest version of the Grant Kit. -// -// Grant Kit Versions are immutable and you won't be able to create a request against an older Grant Kit Version. -// If you want to do this, you will have to roll forward by creating a new Grant Kit Version. -func (s *requests) CreateRequest(ctx context.Context, request shared.RequestParams) (*operations.CreateRequestResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/requests" - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "Request", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.CreateRequestResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 201: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Request - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Request = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetRequestByID - Retrieve a Request by ID -// Returns the details of a request. -func (s *requests) GetRequestByID(ctx context.Context, request operations.GetRequestByIDRequest) (*operations.GetRequestByIDResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/requests/{request_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetRequestByIDResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Request - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Request = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// ListRequests - List Requests -// Returns a list of requests. -// -// Requests are sorted by creation date, descending. -func (s *requests) ListRequests(ctx context.Context) (*operations.ListRequestsResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/requests" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ListRequestsResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out []shared.Request - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Requests = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/reviews.go b/internal/sdk/reviews.go deleted file mode 100755 index 38bd6e2..0000000 --- a/internal/sdk/reviews.go +++ /dev/null @@ -1,343 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/operations" - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "bytes" - "context" - "fmt" - "io" - "net/http" - "strings" -) - -// reviews - Reviews are decisions made by a reviewer on an Access Request. -// -// A Reviewer might approve or deny a request. -// -// https://docs.abbey.io/product/approving-or-denying-access-requests -type reviews struct { - sdkConfiguration sdkConfiguration -} - -func newReviews(sdkConfig sdkConfiguration) *reviews { - return &reviews{ - sdkConfiguration: sdkConfig, - } -} - -// ListReviews - List Reviews -// Returns a list of all the reviews sent to the user. -// -// Reviews are sorted by creation date, descending. -func (s *reviews) ListReviews(ctx context.Context) (*operations.ListReviewsResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url := strings.TrimSuffix(baseURL, "/") + "/reviews" - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ListReviewsResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out []shared.Review - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Reviews = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// ApproveReview - Approve a Review -// Updates the specified review with an approval decision. -func (s *reviews) ApproveReview(ctx context.Context, request operations.ApproveReviewRequest) (*operations.ApproveReviewResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/reviews/{review_id}/approve", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "ReviewUpdateParams", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "PUT", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.ApproveReviewResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Review - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Review = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// DenyReview - Deny a Review -// Updates the specified review with a deny decision. -func (s *reviews) DenyReview(ctx context.Context, request operations.DenyReviewRequest) (*operations.DenyReviewResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/reviews/{review_id}/deny", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - bodyReader, reqContentType, err := utils.SerializeRequestBody(ctx, request, "ReviewUpdateParams", "json") - if err != nil { - return nil, fmt.Errorf("error serializing request body: %w", err) - } - if bodyReader == nil { - return nil, fmt.Errorf("request body is required") - } - - req, err := http.NewRequestWithContext(ctx, "PUT", url, bodyReader) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - req.Header.Set("Content-Type", reqContentType) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.DenyReviewResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Review - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Review = out - } - case httpRes.StatusCode == 400: - fallthrough - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 409: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} - -// GetReviewByID - Retrieve a Review by ID -// Returns the details of a review -func (s *reviews) GetReviewByID(ctx context.Context, request operations.GetReviewByIDRequest) (*operations.GetReviewByIDResponse, error) { - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - url, err := utils.GenerateURL(ctx, baseURL, "/reviews/{review_id}", request, nil) - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("user-agent", fmt.Sprintf("speakeasy-sdk/%s %s %s %s", s.sdkConfiguration.Language, s.sdkConfiguration.SDKVersion, s.sdkConfiguration.GenVersion, s.sdkConfiguration.OpenAPIDocVersion)) - - client := s.sdkConfiguration.SecurityClient - - httpRes, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("error sending request: %w", err) - } - if httpRes == nil { - return nil, fmt.Errorf("error sending request: no response") - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - contentType := httpRes.Header.Get("Content-Type") - - res := &operations.GetReviewByIDResponse{ - StatusCode: httpRes.StatusCode, - ContentType: contentType, - RawResponse: httpRes, - } - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Review - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Review = out - } - case httpRes.StatusCode == 401: - fallthrough - case httpRes.StatusCode == 404: - fallthrough - case httpRes.StatusCode == 429: - fallthrough - default: - switch { - case utils.MatchContentType(contentType, `application/json`): - var out *shared.Error - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out); err != nil { - return nil, err - } - - res.Error = out - } - } - - return res, nil -} diff --git a/internal/sdk/sdk.go b/internal/sdk/sdk.go deleted file mode 100755 index 2ef3668..0000000 --- a/internal/sdk/sdk.go +++ /dev/null @@ -1,219 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package sdk - -import ( - "abbey/v2/internal/sdk/pkg/models/shared" - "abbey/v2/internal/sdk/pkg/utils" - "fmt" - "net/http" - "time" -) - -const ( - // ServerProd - prod - ServerProd string = "prod" - // ServerDev - dev - ServerDev string = "dev" -) - -// ServerList contains the list of servers available to the SDK -var ServerList = map[string]string{ - ServerProd: "https://api.abbey.io/v1", - ServerDev: "http://localhost:8080/v1", -} - -// HTTPClient provides an interface for suplying the SDK with a custom HTTP client -type HTTPClient interface { - Do(req *http.Request) (*http.Response, error) -} - -// String provides a helper function to return a pointer to a string -func String(s string) *string { return &s } - -// Bool provides a helper function to return a pointer to a bool -func Bool(b bool) *bool { return &b } - -// Int provides a helper function to return a pointer to an int -func Int(i int) *int { return &i } - -// Int64 provides a helper function to return a pointer to an int64 -func Int64(i int64) *int64 { return &i } - -// Float32 provides a helper function to return a pointer to a float32 -func Float32(f float32) *float32 { return &f } - -// Float64 provides a helper function to return a pointer to a float64 -func Float64(f float64) *float64 { return &f } - -type sdkConfiguration struct { - DefaultClient HTTPClient - SecurityClient HTTPClient - Security *shared.Security - ServerURL string - Server string - Language string - OpenAPIDocVersion string - SDKVersion string - GenVersion string -} - -func (c *sdkConfiguration) GetServerDetails() (string, map[string]string) { - if c.ServerURL != "" { - return c.ServerURL, nil - } - - if c.Server == "" { - c.Server = "prod" - } - - return ServerList[c.Server], nil -} - -// SDK - Abbey API: The public Abbey API. Used for integrating with Abbey and building interfaces to extend the Abbey platform. -// See https://docs.abbey.io for more information. -type SDK struct { - // APIKeys - API Keys are used to authenticate to the Abbey API. - // - // https://docs.abbey.io/product/managing-api-keys - APIKeys *apiKeys - // ConnectionSpecs - Connection Specs are the templates for creating connections. - // They are used to validate connection parameters and to provide a UI for creating connections. - // - // https://docs.abbey.io - ConnectionSpecs *connectionSpecs - // Connections - Connections are authenticated, with scopes if available, and made available to Abbey Grant Kits at runtime. - // - // https://docs.abbey.io - Connections *connections - // Demo - Abbey Demo - // https://docs.abbey.io/getting-started/quickstart - Demo *demo - // GrantKits - Grant Kits are what you configure in code to control and automatically right-size permissions for resources. - // A Grant Kit has 3 components: - // - // 1. Workflow to configure how someone should get access. - // 2. Policies to configure if someone should get access. - // 3. Output to configure how and where Grants should materialize. - // - // https://docs.abbey.io/getting-started/concepts#grant-kits - GrantKits *grantKits - // Grants - Grants are permissions that reflect the result of an access request going through the process of evaluating - // policies and approval workflows where all approval conditions are met. - // - // Grants may be revoked manually by a user or automatically if a time-based or attribute-based policy is - // included in the corresponding Grant Kit's policy. - // - // https://docs.abbey.io/getting-started/concepts#grants - Grants *grants - // Identities - User metadata used for enriching data. - // Enriched data is used to write richer policies, workflows, and outputs. - // - // https://docs.abbey.io - Identities *identities - // Requests - Requests are Access Requests that users make to get access to a resource. - // - // https://docs.abbey.io/getting-started/concepts#access-requests - Requests *requests - // Reviews - Reviews are decisions made by a reviewer on an Access Request. - // - // A Reviewer might approve or deny a request. - // - // https://docs.abbey.io/product/approving-or-denying-access-requests - Reviews *reviews - - sdkConfiguration sdkConfiguration -} - -type SDKOption func(*SDK) - -// WithServerURL allows the overriding of the default server URL -func WithServerURL(serverURL string) SDKOption { - return func(sdk *SDK) { - sdk.sdkConfiguration.ServerURL = serverURL - } -} - -// WithTemplatedServerURL allows the overriding of the default server URL with a templated URL populated with the provided parameters -func WithTemplatedServerURL(serverURL string, params map[string]string) SDKOption { - return func(sdk *SDK) { - if params != nil { - serverURL = utils.ReplaceParameters(serverURL, params) - } - - sdk.sdkConfiguration.ServerURL = serverURL - } -} - -// WithServer allows the overriding of the default server by name -func WithServer(server string) SDKOption { - return func(sdk *SDK) { - _, ok := ServerList[server] - if !ok { - panic(fmt.Errorf("server %s not found", server)) - } - - sdk.sdkConfiguration.Server = server - } -} - -// WithClient allows the overriding of the default HTTP client used by the SDK -func WithClient(client HTTPClient) SDKOption { - return func(sdk *SDK) { - sdk.sdkConfiguration.DefaultClient = client - } -} - -// WithSecurity configures the SDK to use the provided security details -func WithSecurity(security shared.Security) SDKOption { - return func(sdk *SDK) { - sdk.sdkConfiguration.Security = &security - } -} - -// New creates a new instance of the SDK with the provided options -func New(opts ...SDKOption) *SDK { - sdk := &SDK{ - sdkConfiguration: sdkConfiguration{ - Language: "terraform", - OpenAPIDocVersion: "v1", - SDKVersion: "2.2.1", - GenVersion: "2.81.1", - }, - } - for _, opt := range opts { - opt(sdk) - } - - // Use WithClient to override the default client if you would like to customize the timeout - if sdk.sdkConfiguration.DefaultClient == nil { - sdk.sdkConfiguration.DefaultClient = &http.Client{Timeout: 60 * time.Second} - } - if sdk.sdkConfiguration.SecurityClient == nil { - if sdk.sdkConfiguration.Security != nil { - sdk.sdkConfiguration.SecurityClient = utils.ConfigureSecurityClient(sdk.sdkConfiguration.DefaultClient, sdk.sdkConfiguration.Security) - } else { - sdk.sdkConfiguration.SecurityClient = sdk.sdkConfiguration.DefaultClient - } - } - - sdk.APIKeys = newAPIKeys(sdk.sdkConfiguration) - - sdk.ConnectionSpecs = newConnectionSpecs(sdk.sdkConfiguration) - - sdk.Connections = newConnections(sdk.sdkConfiguration) - - sdk.Demo = newDemo(sdk.sdkConfiguration) - - sdk.GrantKits = newGrantKits(sdk.sdkConfiguration) - - sdk.Grants = newGrants(sdk.sdkConfiguration) - - sdk.Identities = newIdentities(sdk.sdkConfiguration) - - sdk.Requests = newRequests(sdk.sdkConfiguration) - - sdk.Reviews = newReviews(sdk.sdkConfiguration) - - return sdk -} diff --git a/internal/shared/models/grant/grant.go b/internal/shared/models/grant/grant.go new file mode 100644 index 0000000..8d202ec --- /dev/null +++ b/internal/shared/models/grant/grant.go @@ -0,0 +1,17 @@ +package grant + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type Grant struct { + Id types.String `tfsdk:"id"` + GrantKitId types.String `tfsdk:"grant_kit_id"` + GrantKitVersionId types.String `tfsdk:"grant_kit_version_id"` + UserId types.String `tfsdk:"user_id"` + RequestId types.String `tfsdk:"request_id"` + OrganizationId types.String `tfsdk:"organization_id"` + Deleted types.Bool `tfsdk:"deleted"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` +} diff --git a/internal/shared/models/grant_workflow/grant_workflow.go b/internal/shared/models/grant_workflow/grant_workflow.go new file mode 100644 index 0000000..8e403c5 --- /dev/null +++ b/internal/shared/models/grant_workflow/grant_workflow.go @@ -0,0 +1,9 @@ +package grant_workflow + +import ( + "abbey/v2/internal/shared/models/step" +) + +type GrantWorkflow struct { + Steps []step.Step `tfsdk:"steps"` +} diff --git a/internal/provider/type_output.go b/internal/shared/models/output/output.go old mode 100755 new mode 100644 similarity index 50% rename from internal/provider/type_output.go rename to internal/shared/models/output/output.go index 08088cd..6dd97ae --- a/internal/provider/type_output.go +++ b/internal/shared/models/output/output.go @@ -1,11 +1,11 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. +package output -package provider - -import "github.com/hashicorp/terraform-plugin-framework/types" +import ( + "github.com/hashicorp/terraform-plugin-framework/types" +) type Output struct { - Append types.String `tfsdk:"append"` Location types.String `tfsdk:"location"` + Append types.String `tfsdk:"append"` Overwrite types.String `tfsdk:"overwrite"` } diff --git a/internal/shared/models/permission/permission.go b/internal/shared/models/permission/permission.go new file mode 100644 index 0000000..7af6d81 --- /dev/null +++ b/internal/shared/models/permission/permission.go @@ -0,0 +1,4 @@ +package permission + +type Permission struct { +} diff --git a/internal/shared/models/policy/policy.go b/internal/shared/models/policy/policy.go new file mode 100644 index 0000000..0e14628 --- /dev/null +++ b/internal/shared/models/policy/policy.go @@ -0,0 +1,10 @@ +package policy + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type Policy struct { + Bundle types.String `tfsdk:"bundle"` + Query types.String `tfsdk:"query"` +} diff --git a/internal/shared/models/request/request.go b/internal/shared/models/request/request.go new file mode 100644 index 0000000..1bcf465 --- /dev/null +++ b/internal/shared/models/request/request.go @@ -0,0 +1,21 @@ +package request + +import ( + "abbey/v2/internal/shared/models/review" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type Request struct { + Id types.String `tfsdk:"id"` + GrantKitId types.String `tfsdk:"grant_kit_id"` + GrantKitVersionId types.String `tfsdk:"grant_kit_version_id"` + GrantKitName types.String `tfsdk:"grant_kit_name"` + Reason types.String `tfsdk:"reason"` + UserId types.String `tfsdk:"user_id"` + Status types.String `tfsdk:"status"` + Reviews []review.Review `tfsdk:"reviews"` + GrantId types.String `tfsdk:"grant_id"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` + PullRequest types.String `tfsdk:"pull_request"` +} diff --git a/internal/shared/models/request_status/request_status.go b/internal/shared/models/request_status/request_status.go new file mode 100644 index 0000000..5f806b4 --- /dev/null +++ b/internal/shared/models/request_status/request_status.go @@ -0,0 +1,4 @@ +package request_status + +type RequestStatus struct { +} diff --git a/internal/shared/models/review/review.go b/internal/shared/models/review/review.go new file mode 100644 index 0000000..d737567 --- /dev/null +++ b/internal/shared/models/review/review.go @@ -0,0 +1,23 @@ +package review + +import ( + "abbey/v2/internal/shared/models/grant" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type Review struct { + Id types.String `tfsdk:"id"` + UserId types.String `tfsdk:"user_id"` + UserEmail types.String `tfsdk:"user_email"` + RequestId types.String `tfsdk:"request_id"` + Status types.String `tfsdk:"status"` + RequestReason types.String `tfsdk:"request_reason"` + Reason types.String `tfsdk:"reason"` + GrantKitVersionId types.String `tfsdk:"grant_kit_version_id"` + GrantKitName types.String `tfsdk:"grant_kit_name"` + GrantId types.String `tfsdk:"grant_id"` + Grant *grant.Grant `tfsdk:"grant"` + CreatedAt types.String `tfsdk:"created_at"` + UpdatedAt types.String `tfsdk:"updated_at"` + PullRequest types.String `tfsdk:"pull_request"` +} diff --git a/internal/shared/models/review_status/review_status.go b/internal/shared/models/review_status/review_status.go new file mode 100644 index 0000000..aef2bc2 --- /dev/null +++ b/internal/shared/models/review_status/review_status.go @@ -0,0 +1,4 @@ +package review_status + +type ReviewStatus struct { +} diff --git a/internal/shared/models/reviewers/reviewers.go b/internal/shared/models/reviewers/reviewers.go new file mode 100644 index 0000000..538d2ba --- /dev/null +++ b/internal/shared/models/reviewers/reviewers.go @@ -0,0 +1,10 @@ +package reviewers + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type Reviewers struct { + OneOf types.List `tfsdk:"one_of"` + AllOf types.List `tfsdk:"all_of"` +} diff --git a/internal/shared/models/step/step.go b/internal/shared/models/step/step.go new file mode 100644 index 0000000..1c4be87 --- /dev/null +++ b/internal/shared/models/step/step.go @@ -0,0 +1,11 @@ +package step + +import ( + "abbey/v2/internal/shared/models/policy" + "abbey/v2/internal/shared/models/reviewers" +) + +type Step struct { + Reviewers *reviewers.Reviewers `tfsdk:"reviewers"` + SkipIf []policy.Policy `tfsdk:"skip_if"` +} diff --git a/internal/tools/tools.go b/internal/tools/tools.go deleted file mode 100644 index d72c970..0000000 --- a/internal/tools/tools.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build tools - -package tools - -import ( - _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" -) diff --git a/internal/utils/utils.go b/internal/utils/utils.go new file mode 100644 index 0000000..2100d69 --- /dev/null +++ b/internal/utils/utils.go @@ -0,0 +1,181 @@ +package utils + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "reflect" +) + +func Pointer[T any](v T) *T { + return &v +} + +func NullableString(s *string) types.String { + if s != nil { + return types.StringValue(*s) + } + return types.StringNull() +} + +func NullableBool(b *bool) types.Bool { + if b != nil { + return types.BoolValue(*b) + } + return types.BoolNull() +} + +func NullableInt64(i *int64) types.Int64 { + if i != nil { + return types.Int64Value(*i) + } + return types.Int64Null() +} + +func NullableTfStateObject[T any, R any](source *T, fn func(t *T) R) *R { + if source != nil { + r := fn(source) + return &r + } + return nil +} + +func NullableObject[T any, R any](source *T, value R) *R { + if source != nil { + return &value + } + + return nil +} + +func NullableFloat64(f *float64) types.Float64 { + if f != nil { + return types.Float64Value(*f) + } + return types.Float64Null() +} + +func MapList[T, R any](from []T, f func(T) R) []R { + if from == nil { + return nil + } + to := make([]R, len(from)) + for i, v := range from { + to[i] = f(v) + } + return to +} + +func ToList(ctx context.Context, from any, toType attr.Type, diagnostics *diag.Diagnostics) types.List { + result, err := types.ListValueFrom(ctx, toType, from) + if err != nil { + diagnostics.Append(err.Warnings()...) + diagnostics.Append(err.Errors()...) + return types.ListUnknown(toType) + } + + return result +} + +func MapArrayQueryParams[T any](ctx context.Context, from types.List, diagnostics *diag.Diagnostics) []T { + params := make([]T, 0) + + diags := from.ElementsAs(ctx, params, false) + + if diags.HasError() { + diagnostics.Append(diags...) + } + + return params +} + +// ToMap toType expects a types.MapType +func ToMap(ctx context.Context, from any, toType attr.Type, diagnostics *diag.Diagnostics) types.Map { + mapType, ok := toType.(types.MapType) + + if !ok { + diagnostics.AddError("Cannot convert to Map", fmt.Sprintf("Error converting %v", toType)) + return types.MapUnknown(toType) + } + + result, err := types.MapValueFrom(ctx, mapType.ElemType, from) + if err != nil { + diagnostics.Append(err.Warnings()...) + diagnostics.Append(err.Errors()...) + return types.MapUnknown(toType) + } + + return result +} + +func FromListToPrimitiveSlice[T any](ctx context.Context, from types.List, diagnostics *diag.Diagnostics) []T { + elements := from.Elements() + result := make([]T, len(elements)) + for i, elem := range elements { + conversionMethod, err := getConversionMethodName(from.ElementType(ctx)) + if err != nil { + diagnostics.Append(diag.NewErrorDiagnostic("conversion error", err.Error())) + return nil + } + + res := reflect.ValueOf(elem).MethodByName(conversionMethod).Call([]reflect.Value{}) + result[i] = res[0].Interface().(T) + + } + return result +} + +func FromTypesMapToMap[T any](ctx context.Context, from types.Map, diagnostics *diag.Diagnostics) map[string]T { + m := make(map[string]T) + + diags := from.ElementsAs(ctx, &m, false) + + if diags.HasError() { + diagnostics.Append(diags...) + } + + return m +} + +// PopulateModelData populates target interface with data from plan, replacing null and unknown with empty +// planGetterFn is a function which retrieves data from the request Plan, State or Config. Examples: req.State.Get, req.Plan.Get +// target should be a pointer +func PopulateModelData(ctx context.Context, target interface{}, diagnostics diag.Diagnostics, planGetterFn func(ctx context.Context, target interface{}) diag.Diagnostics) { + var obj types.Object + + diagnostics.Append(planGetterFn(ctx, &obj)...) + + diagnostics.Append(obj.As(ctx, target, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) +} + +func TypeAtPath(ctx context.Context, p path.Path, state tfsdk.State, diagnostics *diag.Diagnostics) attr.Type { + targetType, diags := state.Schema.TypeAtPath(ctx, p) + + if diags.HasError() { + diagnostics.Append(diags...) + } + + return targetType +} + +func getConversionMethodName(t attr.Type) (string, error) { + if t.Equal(types.StringType) { + return "ValueString", nil + } else if t.Equal(types.BoolType) { + return "ValueBool", nil + } else if t.Equal(types.Float64Type) { + return "ValueFloat64", nil + } else if t.Equal(types.Int64Type) { + return "ValueInt64", nil + } else { + return "", fmt.Errorf("unsupported type %s", t.String()) + } +} diff --git a/internal/validators/DateValidator.go b/internal/validators/DateValidator.go deleted file mode 100755 index 7e84a8f..0000000 --- a/internal/validators/DateValidator.go +++ /dev/null @@ -1,50 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package validators - -import ( - "abbey/v2/internal/sdk/pkg/types" - "context" - "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" -) - -var _ validator.String = DateValidator{} - -type DateValidator struct { -} - -func (validator DateValidator) Description(ctx context.Context) string { - return "value must be a string in YYYY-MM-DD format" -} - -func (validator DateValidator) MarkdownDescription(ctx context.Context) string { - return validator.Description(ctx) -} - -func (validator DateValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { - // Only validate the attribute configuration value if it is known. - if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { - return - } - - if _, err := types.NewDateFromString(req.ConfigValue.ValueString()); err != nil { - resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( - req.Path, - validator.MarkdownDescription(ctx), - req.ConfigValue.ValueString(), - )) - return - } -} - -// IsDate returns an AttributeValidator which ensures that any configured -// attribute value: -// -// - Is a String. -// - Is in YYYY-MM-DD Format. -// -// Null (unconfigured) and unknown (known after apply) values are skipped. -func IsValidDate() validator.String { - return DateValidator{} -} diff --git a/internal/validators/ExactlyOneChild.go b/internal/validators/ExactlyOneChild.go deleted file mode 100755 index 5741558..0000000 --- a/internal/validators/ExactlyOneChild.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package validators - -import ( - "context" - "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" -) - -var _ validator.Object = exactlyOneChild{} - -// exactlyOneChild validates if the provided value is of type string and can be parsed as JSON. -type exactlyOneChild struct { -} - -func (validator exactlyOneChild) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { - // Only validate the attribute configuration value if it is known. - if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { - return - } - defined := make(map[string]bool) - count := 0 - for key, attr := range req.ConfigValue.Attributes() { - if attr.IsUnknown() || attr.IsNull() { - continue - } - defined[key] = true - count++ - } - if count != 1 { - resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( - req.Path, - validator.MarkdownDescription(ctx), - req.ConfigValue.String(), - )) - } -} - -func (validator exactlyOneChild) Description(ctx context.Context) string { - return "value must have exactly one child attribute defined" -} - -func (validator exactlyOneChild) MarkdownDescription(ctx context.Context) string { - return validator.Description(ctx) -} - -// ExactlyOneChild returns an AttributeValidator which ensures that any configured -// attribute object has only one child attribute. -// Null (unconfigured) and unknown values are skipped. -func ExactlyOneChild() validator.Object { - return exactlyOneChild{} -} diff --git a/internal/validators/JSONParseValidator.go b/internal/validators/JSONParseValidator.go deleted file mode 100755 index 3a341e1..0000000 --- a/internal/validators/JSONParseValidator.go +++ /dev/null @@ -1,51 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package validators - -import ( - "context" - "encoding/json" - "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" -) - -var _ validator.String = JSONParseValidator{} - -// JSONParseValidator validates if the provided value is of type string and can be parsed as JSON. -type JSONParseValidator struct { -} - -func (validator JSONParseValidator) Description(ctx context.Context) string { - return "value must be parsable as JSON" -} - -func (validator JSONParseValidator) MarkdownDescription(ctx context.Context) string { - return validator.Description(ctx) -} - -func (validator JSONParseValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { - // Only validate the attribute configuration value if it is known. - if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { - return - } - - if !json.Valid([]byte(req.ConfigValue.ValueString())) { - resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( - req.Path, - validator.MarkdownDescription(ctx), - req.ConfigValue.ValueString(), - )) - return - } -} - -// IsValidJSON returns an AttributeValidator which ensures that any configured -// attribute value: -// -// - Is a String. -// - Is considered valid JSON. -// -// Null (unconfigured) and unknown (known after apply) values are skipped. -func IsValidJSON() validator.String { - return JSONParseValidator{} -} diff --git a/internal/validators/RFC3339Validator.go b/internal/validators/RFC3339Validator.go deleted file mode 100755 index 42c90dc..0000000 --- a/internal/validators/RFC3339Validator.go +++ /dev/null @@ -1,50 +0,0 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - -package validators - -import ( - "context" - "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "time" -) - -var _ validator.String = RFC3339TimeValidator{} - -type RFC3339TimeValidator struct { -} - -func (validator RFC3339TimeValidator) Description(ctx context.Context) string { - return "value must be a string in RFC3339 format" -} - -func (validator RFC3339TimeValidator) MarkdownDescription(ctx context.Context) string { - return validator.Description(ctx) -} - -func (validator RFC3339TimeValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { - // Only validate the attribute configuration value if it is known. - if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() { - return - } - - if _, err := time.Parse(time.RFC3339, req.ConfigValue.ValueString()); err != nil { - resp.Diagnostics.Append(validatordiag.InvalidAttributeTypeDiagnostic( - req.Path, - validator.MarkdownDescription(ctx), - req.ConfigValue.ValueString(), - )) - return - } -} - -// IsRFC3339 returns an AttributeValidator which ensures that any configured -// attribute value: -// -// - Is a String. -// - Is in RFC3339 Format. -// -// Null (unconfigured) and unknown (known after apply) values are skipped. -func IsRFC3339() validator.String { - return RFC3339TimeValidator{} -} diff --git a/main.go b/main.go old mode 100755 new mode 100644 index a537239..7891092 --- a/main.go +++ b/main.go @@ -1,5 +1,3 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - package main import ( @@ -23,8 +21,11 @@ import ( var ( // these will be set by the goreleaser configuration - // to appropriate values for the compiled binary + // to appropriate values for the compiled binary. version string = "dev" + + // goreleaser can pass other information to the main package, such as the specific commit + // https://goreleaser.com/cookbooks/using-main.version/ ) func main() { @@ -34,7 +35,8 @@ func main() { flag.Parse() opts := providerserver.ServeOpts{ - Address: "registry.terraform.io/abbeylabs/abbey", + // TODO: Update this string with the published name of your provider. + Address: "registry.terraform.io/hashicorp/abbey", Debug: debug, } @@ -44,3 +46,5 @@ func main() { log.Fatal(err.Error()) } } + +// c029837e0e474b76bc487506e8799df5e3335891efe4fb02bda7a1441840310c diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl deleted file mode 100644 index 6c747eb..0000000 --- a/templates/index.md.tmpl +++ /dev/null @@ -1,63 +0,0 @@ ---- -page_title: "Provider: Abbey" -description: |- - The Abbey provider is used by security teams and DevOps/DevSecOps engineers to automate and secure - access to sensitive resources. ---- - -# Abbey Provider - -The Abbey provider is used by security teams and DevOps/DevSecOps engineers to automate and secure -access to sensitive resources in their existing cloud infrastructure. - -Resources in this provider interact with endpoints from the Abbey API and needs to be -configured with credentials before it can used. - -## Background - -Abbey is a platform for security teams and DevOps/DevSecOps engineers to -automate and secure access to sensitive resources. - -With Abbey, you can improve your security and compliance programs by automatically controlling -and right-sizing permissions so the risks around unauthorized access is limited in the event of a breach. - -You do this by leveraging your normal Infrastructure as Code (IaC) tooling — -Terraform, CI/CD systems, secrets managers, and Terraform wrappers. -Abbey provides a Terraform plugin and platform that extends your Infrastructure as Code capabilities -from Infrastructure to Identity, Access, and Management (IAM). - -## Contributing - -Development happens in the [GitHub repo](https://github.com/abbeylabs/terraform-provider-abbey): - -- [Releases](https://github.com/abbeylabs/terraform-provider-abbey/releases) -- [Issues](https://github.com/abbeylabs/terraform-provider-abbey/issues) - -## Example Usage - -{{ tffile "examples/provider-install-verification/main.tf" }} - -## Authentication - -Abbey provides the following methods for authenticating to the Abbey API: - -- Abbey Token - -### Generating Tokens - -You can generate an Abbey Token by: - -- [Abbey Developers Dashboard](https://app.abbey.io/developers) -> New API Key -> Create - -### Using Tokens - -Configure your Abbey `provider` block with a `bearer_auth` string. - -```hcl -provider "abbey" { - bearer_auth = "" -} -``` - -For better security practice, you should place your token into a variable in your `variables.tf` file and set it -using an environment variable or secret store. diff --git a/terraform-registry-manifest.json b/terraform-registry-manifest.json old mode 100755 new mode 100644 index fec2a56..295001a --- a/terraform-registry-manifest.json +++ b/terraform-registry-manifest.json @@ -1,6 +1,6 @@ { - "version": 1, - "metadata": { - "protocol_versions": ["6.0"] - } + "version": 1, + "metadata": { + "protocol_versions": ["6.0"] + } } diff --git a/tools/tools.go b/tools/tools.go old mode 100755 new mode 100644 index 4f42a8c..2c4f8fb --- a/tools/tools.go +++ b/tools/tools.go @@ -1,5 +1,3 @@ -// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. - //go:build tools package tools diff --git a/validator/rfc3986.go b/validator/rfc3986.go deleted file mode 100644 index bee2dc6..0000000 --- a/validator/rfc3986.go +++ /dev/null @@ -1,45 +0,0 @@ -package validator - -import ( - "context" - "fmt" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "net/url" -) - -// IsRFC3986 checks if the string is an RFC 3986 URI. -func IsRFC3986() rfc3986Validator { - return rfc3986Validator{} -} - -type rfc3986Validator struct { -} - -// Description returns a plain text description of the validator's behavior, suitable for a practitioner to understand its impact. -func (v rfc3986Validator) Description(ctx context.Context) string { - return "string must be in RFC 3986 format" -} - -// MarkdownDescription returns a markdown formatted description of the validator's behavior, suitable for a practitioner to understand its impact. -func (v rfc3986Validator) MarkdownDescription(ctx context.Context) string { - return "string must be in RFC 3986 format" -} - -// ValidateString runs the main validation logic of the validator, reading configuration data out of `req` and updating `resp` with diagnostics. -func (v rfc3986Validator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { - // If the value is unknown or null, there is nothing to validate. - if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() { - return - } - - _, err := url.ParseRequestURI(req.ConfigValue.ValueString()) - - if err != nil { - resp.Diagnostics.AddAttributeError( - req.Path, - "Invalid String Format", - fmt.Sprintf("String must be in RFC 3986 format: %s", err), - ) - return - } -}