Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42e2126217 | ||
|
|
5d098ac71d | ||
|
|
949976ec19 | ||
|
|
49f692e7a8 | ||
|
|
a75ac95465 | ||
|
|
7fd6d3f3e5 | ||
|
|
bdd27e2562 | ||
|
|
f17f05ec82 |
No files matched your search
@@ -0,0 +1,11 @@
|
||||
## PCI review checklist
|
||||
|
||||
<!-- heimdall_github_prtemplate:grc-pci_dss-2024-01-05 -->
|
||||
|
||||
- [ ] I have documented a clear reason for, and description of, the change I am making.
|
||||
|
||||
- [ ] If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
|
||||
|
||||
- [ ] If applicable, I've documented the impact of any changes to security controls.
|
||||
|
||||
Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.
|
||||
@@ -8,3 +8,8 @@ plan.tfplan
|
||||
# IntelliJ IDEA project files
|
||||
.idea
|
||||
*.iprg
|
||||
|
||||
.DS_Store
|
||||
|
||||
.env
|
||||
.envrc
|
||||
@@ -1,66 +1,69 @@
|
||||
module github.com/hashicorp/boundary-plugin-aws
|
||||
|
||||
go 1.21
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.2
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.186.0
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.37.2
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.66.1
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2
|
||||
github.com/aws/smithy-go v1.22.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.0
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.52.2
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.2
|
||||
github.com/aws/smithy-go v1.24.0
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/uuid v1.4.0
|
||||
github.com/hashicorp/boundary/sdk v0.0.43-0.20240717182311-a20aae98794a
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hashicorp/boundary/sdk v0.0.51
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.0.0
|
||||
github.com/hashicorp/terraform-json v0.14.0
|
||||
github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.2
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0
|
||||
github.com/hashicorp/terraform-json v0.23.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
google.golang.org/grpc v1.61.0
|
||||
google.golang.org/protobuf v1.35.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
google.golang.org/grpc v1.68.0
|
||||
google.golang.org/protobuf v1.36.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.33 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.32 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.39 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.2 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/eventlogger v0.2.6-0.20231025104552-802587e608f0 // indirect
|
||||
github.com/hashicorp/eventlogger/filters/encrypt v0.1.8-0.20231025104552-802587e608f0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.14 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.16 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.6 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/go-version v1.5.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/pointerstructure v1.2.1 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/zclconf/go-cty v1.10.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/zclconf/go-cty v1.15.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
@@ -4,56 +4,52 @@ github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7Y
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
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/aws/aws-sdk-go-v2 v1.20.1/go.mod h1:NU06lETsFm8fUC6ZjhgDpVBcGZTFQ6XM+LZWZxMI4ac=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.33 h1:JKcw5SFxFW/rpM4mOPjv0VQ11E2kxW13F3exWOy7VZU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.33/go.mod h1:hXO/l9pgY3K5oZJldamP0pbZHdPqqk+4/maa7DSD3cA=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.32 h1:lIH1eKPcCY1ylR4B6PkBGRWMHO3aVenOKJHWiS4/G2w=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.32/go.mod h1:lL8U3v/Y79YRG69WlAho0OHIKUXCyFvSXaIvfo81sls=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.8 h1:DK/9C+UN/X+1+Wm8pqaDksQr2tSLzq+8X1/rI/ZxKEQ=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.8/go.mod h1:ce7BgLQfYr5hQFdy67oX2svto3ufGtm6oBvmsHScI1Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38/go.mod h1:qggunOChCMu9ZF/UkAfhTz25+U2rLVb3ya0Ua6TTfCA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.32/go.mod h1:0ZXSqrty4FtQ7p8TEuRde/SZm9X05KT18LAUlR40Ln0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.39 h1:fc0ukRAiP1syoSGZYu+DaE+FulSYhTiJ8WpVu5jElU4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.39/go.mod h1:WLAW8PT7+JhjZfLSWe7WEJaJu0GNo0cKc2Zyo003RBs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 h1:7edmS3VOBDhK00b/MwGtGglCm7hhwNYnjJs/PgFdMQE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21/go.mod h1:Q9o5h4HoIWG8XfzxqiuK/CGUbepCJ8uTlaE3bAbxytQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.186.0 h1:n2l2WeV+lEABrGwG/4MsE0WFEbd3j7yKsmZzbnEm5CY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.186.0/go.mod h1:kYXaB4FzyhEJjvrJ84oPnMElLiEAjGxxUunVW2tBSng=
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.37.2 h1:E7vCDUFeDN8uOk8Nb2d4E1howWS1TR4HrKABXsvttIs=
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.37.2/go.mod h1:QzMecFrIFYJ1cyxjlUoIFRzYSDX19gdqYUd0Tyws2J8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 h1:4FMHqLfk0efmTqhXVRL5xYRqlEBNBiRI7N6w4jsEdd4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2/go.mod h1:LWoqeWlK9OZeJxsROW2RqrSPvQHKTpp69r/iDjwsSaw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.32/go.mod h1:4jwAWKEkCR0anWk5+1RbfSg1R5Gzld7NLiuaq5bTR/Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.66.1 h1:MkQ4unegQEStiQYmfFj+Aq5uTp265ncSmm0XTQwDwi0=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.66.1/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.2 h1:A2RlEMo4SJSwbNoUUgkxTAEMduAy/8wG3eB2b2lP4gY=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.13.2/go.mod h1:ju+nNXUunfIFamXUIZQiICjnO/TPlOmWcYhZcSy7xaE=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.2 h1:OJELEgyaT2kmaBGZ+myyZbTTLobfe3ox3FSh5eYK9Qs=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.2/go.mod h1:ubDBBaDFs1GHijSOTi8ljppML15GLG0HxhILtbjNNYQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.21.2/go.mod h1:FQ/DQcOfESELfJi5ED+IPPAjI5xC6nxtSolVVB773jM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 h1:CiS7i0+FUe+/YY1GvIBLLrR/XNGZ4CtM1Ll0XavNuVo=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2/go.mod h1:HtaiBI8CjYoNVde8arShXb94UbQQi9L4EMr6D+xGBwo=
|
||||
github.com/aws/smithy-go v1.14.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM=
|
||||
github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.2 h1:4liUsdEpUUPZs5WVapsJLx5NPmQhQdez7nYFcovrytk=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.2/go.mod h1:l0hs06IFz1eCT+jTacU/qZtC33nvcnLADAPL/XyrkZI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.2 h1:qZry8VUyTK4VIo5aEdUcBjPZHL2v4FyQ3QEOaWcFLu4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.2/go.mod h1:YUqm5a1/kBnoK+/NY5WEiMocZihKSo15/tJdmdXnM5g=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 h1:WZVR5DbDgxzA0BJeudId89Kmgy6DIU4ORpxwsVHz0qA=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14/go.mod h1:Dadl9QO0kHgbrH1GRqGiZdYtW5w+IXXaBNCHTIaheM4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14/go.mod h1:VymhrMJUWs69D8u0/lZ7jSB6WgaG/NqHi3gX0aYf6U0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14/go.mod h1:1ipeGBMAxZ0xcTm6y6paC2C/J6f6OO7LBODV9afuAyM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 h1:JX70yGKLj25+lMC5Yyh8wBtvB01GDilyRuJvXJ4piD0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24/go.mod h1:+Ln60j9SUTD0LEwnhEB0Xhg61DHqplBrbZpLgyjoEHg=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0 h1:RhSoBFT5/8tTmIseJUXM6INTXTQDF8+0oyxWBnozIms=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0/go.mod h1:mzj8EEjIHSN2oZRXiw1Dd+uB4HZTl7hC8nBzX9IZMWw=
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.52.2 h1:li0ooCUfHIivHn8nB3LstP6HgdNefwu5gnXE4MLVz/U=
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.52.2/go.mod h1:PuHz5kGh1jtsNpjezdYhRp7xgn6DzCNJJfQt7O7U9Aw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 h1:gvZOjQKPxFXy1ft3QnEyXmT+IqneM9QAUWlM3r0mfqw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5/go.mod h1:DLWnfvIcm9IET/mmjdxeXbBKmTCm0ZB8p1za9BVteM8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 h1:FIouAnCE46kyYqyhs0XEBDFFSREtdnr8HQuLPQPLCrY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14/go.mod h1:UTwDc5COa5+guonQU8qBikJo1ZJ4ln2r1MkF7Dqag1E=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 h1:P1doBzv5VEg1ONxnJss1Kh5ZG/ewoIE4MQtKKc6Crgg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.2 h1:MxMBdKTYBjPQChlJhi4qlEueqB1p1KcbTEa7tD5aqPs=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.2/go.mod h1:iS6EPmNeqCsGo+xQmXv0jIMjyYtQfnwg36zl2FwEouk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.5 h1:ksUT5KtgpZd3SAiFJNJ0AFEJVva3gjBmN7eXUZjzUwQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.5/go.mod h1:av+ArJpoYf3pgyrj6tcehSFW+y9/QvAY8kMooR9bZCw=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10 h1:GtsxyiF3Nd3JahRBJbxLCCdYW9ltGQYrFWg8XdkGDd8=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10/go.mod h1:/j67Z5XBVDx8nZVp9EuFM9/BS5dvBznbqILGuu73hug=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.2 h1:a5UTtD4mHBU3t0o6aHQZFJTNKVfxFWfPX7J0Lr7G+uY=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.2/go.mod h1:6TxbXoDSgBQ225Qd8Q+MbxUxUh6TtNKwbRt/EPS9xso=
|
||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
@@ -61,26 +57,20 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
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/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
|
||||
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.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.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/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/boundary/sdk v0.0.43-0.20240717182311-a20aae98794a h1:SwVze6sYE5o+J9qdcgj29auY1k6O8oSo9DC2+2Gb9rw=
|
||||
github.com/hashicorp/boundary/sdk v0.0.43-0.20240717182311-a20aae98794a/go.mod h1:9iOT7kDM6mYcSkKxNuZlv8rP7U5BG1kXoevjLLL8lNQ=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/boundary/sdk v0.0.51 h1:a7XpHNTYaeBXRhJkc8MC0siPtfJELYH/ibjw/0UbJEg=
|
||||
github.com/hashicorp/boundary/sdk v0.0.51/go.mod h1:gSrMTppD30IPVsUqs4SwQowu+OlR5/+58draey++SkQ=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -90,18 +80,18 @@ github.com/hashicorp/eventlogger/filters/encrypt v0.1.8-0.20231025104552-802587e
|
||||
github.com/hashicorp/eventlogger/filters/encrypt v0.1.8-0.20231025104552-802587e608f0/go.mod h1:tMywUTIvdB/FXhwm6HMTt61C8/eODY6gitCHhXtyojg=
|
||||
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-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-kms-wrapping/plugin/v2 v2.0.5 h1:jrnDfQm2hCQ0/hEselgqzV4fK16gpZoY0OWGZpVPNHM=
|
||||
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.5/go.mod h1:psh1qKep5ukvuNobFY/hCybuudlkkACpmazOsCgX5Rg=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.14 h1:1ZuhfnZgRnLK8S0KovJkoTCRIQId5pv3sDR7pG5VQBw=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.14/go.mod h1:0dWtzl2ilqKpavgM3id/kFK9L3tjo6fS4OhbVPSYpnQ=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.7 h1:gM4OwbF16Cmfxt2QMkoGMQbRTfYFZLvDMPgU3rM3KIo=
|
||||
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.7/go.mod h1:7ZMHVluyqgHgEuTADeDzFNWoA9mnyPfdiK8Tk2Bct1c=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.16 h1:WZeXfD26QMWYC35at25KgE021SF9L3u9UMHK8fJAdV0=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.16/go.mod h1:ZiKZctjRTLEppuRwrttWkp71VYMbTTCkazK4xT7U/NQ=
|
||||
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.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y=
|
||||
github.com/hashicorp/go-plugin v1.5.2/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4=
|
||||
github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.0.0 h1:ca5TSI4AgaOncPpyzLDtCGjVEtKukONpeM95vFxXCOQ=
|
||||
github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.0.0/go.mod h1:7CUvZtfTp2U0CYQCLzMtS2ngckjAZePSfwrE2aeDP1M=
|
||||
github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg=
|
||||
github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0=
|
||||
github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.2 h1:KlDrZWx/wYpnUcFPB0s9uhPjyNZoeIfhrV2MN/Ly76s=
|
||||
github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.2/go.mod h1:6+rVulOPNCQbL3Xv2iLCqM0JmU2WO2wRzP1C6hBKeB8=
|
||||
github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw=
|
||||
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng=
|
||||
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw=
|
||||
@@ -109,8 +99,8 @@ github.com/hashicorp/go-secure-stdlib/configutil/v2 v2.0.11 h1:uPW2Wn0YlmI9RGSkZ
|
||||
github.com/hashicorp/go-secure-stdlib/configutil/v2 v2.0.11/go.mod h1:uis9dCmOzXuOaRyXq+1Foh31kcvXKoWogjNnhfjHfW8=
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.9 h1:0S0ctJ7Ra8O7ap+/3fZUnzJ3VzJyirWS/WnNCuOYtZY=
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.9/go.mod h1:TNNdgtjLgVDbrgFcyCKrlAicIl3dZF94swJltyGUX2M=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 h1:iBt4Ew4XEGLfh6/bPk4rSYmuZJGizr6/x/AEizP0CQc=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8/go.mod h1:aiJI+PIApBRQG7FZTEBx5GiiX+HbOHilUdNxUZi4eV0=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0=
|
||||
github.com/hashicorp/go-secure-stdlib/pluginutil/v2 v2.0.6 h1:ZYv2XA+tEfFXIToR2jmBgVqQU9gERt0APbWqmUoNGnY=
|
||||
github.com/hashicorp/go-secure-stdlib/pluginutil/v2 v2.0.6/go.mod h1:ggFN8dlaLWS2R1gymBbCrvXM/bkZP7hEAa4seqDwhyg=
|
||||
github.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1 h1:SMGUnbpAcat8rIKHkBPjfv81yC46a8eCNZ2hsR2l1EI=
|
||||
@@ -120,17 +110,17 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
|
||||
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.3 h1:xbrxd0U9XQW8qL1BAz2XrAjAF/P2vcqUTAues9c24B8=
|
||||
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.3/go.mod h1:LWq2Sy8UoKKuK4lFuCNWSjJj57MhNNf2zzBWMtkAIX4=
|
||||
github.com/hashicorp/go-sockaddr v1.0.5 h1:dvk7TIXCZpmfOlM+9mlcrWmWjw/wlKT+VDq2wMvfPJU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.5/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI=
|
||||
github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I=
|
||||
github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI=
|
||||
github.com/hashicorp/go-uuid v1.0.2/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 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
|
||||
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
|
||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
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-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI=
|
||||
github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c=
|
||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
|
||||
@@ -139,10 +129,6 @@ github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f h1:E87tDTVS5W65euzixn7clSzK66puSt1H4I5SC0EmHH4=
|
||||
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f/go.mod h1:3J2qVK16Lq8V+wfiL2lPeDZ7UWMxk5LemerHa1p6N00=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
@@ -151,22 +137,18 @@ 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/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
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-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
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.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
@@ -185,49 +167,38 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
|
||||
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/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/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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0=
|
||||
github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
|
||||
github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=
|
||||
github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -238,16 +209,13 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
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.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@@ -258,28 +226,20 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg=
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe h1:0poefMBYvYbs7g5UkjS6HcxBPaTRAmznle9jnxYoAI8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
||||
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
|
||||
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
||||
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.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -130,7 +130,7 @@ func GetCredentialsConfig(secrets *structpb.Struct, attrs *CredentialAttributes,
|
||||
|
||||
cfg, err := awsutil.NewCredentialsConfig(opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus(err.Error())
|
||||
return nil, errors.BadRequestStatus("%s", err.Error())
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
|
||||
@@ -206,13 +206,7 @@ func (s *AwsCredentialPersistedState) DeleteCreds(ctx context.Context) error {
|
||||
|
||||
// GenerateCredentialChain returns a AWS configuration for the credentials in the state.
|
||||
func (s *AwsCredentialPersistedState) GenerateCredentialChain(ctx context.Context) (*aws.Config, error) {
|
||||
// Default `WithSharedCredentials` is `true` - This disables the ability to
|
||||
// read credentials from environment variables because we set the default
|
||||
// profile options, so we need to set it to false (see
|
||||
// awsutil@v2.(*CredentialsConfig).generateAwsConfigOptions) for extra
|
||||
// details.
|
||||
opts := append(s.testOpts, awsutil.WithSharedCredentials(false))
|
||||
return s.CredentialsConfig.GenerateCredentialChain(ctx, opts...)
|
||||
return s.CredentialsConfig.GenerateCredentialChain(ctx, s.testOpts...)
|
||||
}
|
||||
|
||||
// ToMap returns a map of the credentials stored in the persisted state.
|
||||
|
||||
@@ -73,7 +73,7 @@ func InvalidArgumentError(msg string, f map[string]string) error {
|
||||
sort.Strings(fieldMsgs)
|
||||
msg = fmt.Sprintf("%s: [%s]", msg, strings.Join(fieldMsgs, ", "))
|
||||
}
|
||||
return BadRequestStatus(msg)
|
||||
return BadRequestStatus("%s", msg)
|
||||
}
|
||||
|
||||
// ParseAWSError converts an aws service error into a RPC status. This method
|
||||
|
||||
+1
-1
@@ -32,6 +32,6 @@ type AwsPlugin struct {
|
||||
func NewAwsPlugin() *AwsPlugin {
|
||||
return &AwsPlugin{
|
||||
HostPlugin: &host.HostPlugin{},
|
||||
StoragePlugin: &storage.StoragePlugin{},
|
||||
StoragePlugin: storage.New(),
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ func (p *HostPlugin) OnCreateCatalog(ctx context.Context, req *pb.OnCreateCatalo
|
||||
|
||||
persistedProto, err := catalogState.toProto()
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus(err.Error())
|
||||
return nil, errors.BadRequestStatus("%s", err.Error())
|
||||
}
|
||||
|
||||
return &pb.OnCreateCatalogResponse{
|
||||
@@ -227,7 +227,7 @@ func (p *HostPlugin) OnUpdateCatalog(ctx context.Context, req *pb.OnUpdateCatalo
|
||||
|
||||
persistedProto, err := catalogState.toProto()
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus(err.Error())
|
||||
return nil, errors.BadRequestStatus("%s", err.Error())
|
||||
}
|
||||
|
||||
return &pb.OnUpdateCatalogResponse{
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
@@ -24,14 +25,24 @@ import (
|
||||
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/storagebuckets"
|
||||
pb "github.com/hashicorp/boundary/sdk/pbs/plugin"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
// Ensure that we are implementing StoragePluginServiceServer
|
||||
var _ pb.StoragePluginServiceServer = (*StoragePlugin)(nil)
|
||||
|
||||
// clientCache caches previously initialized S3API clients created with a RoleARN attribute.
|
||||
type clientCache struct {
|
||||
// cache is a map of cached s3 clients. The key of the map
|
||||
// is the public id of the storage bucket
|
||||
cache map[string]S3API
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// StoragePlugin implements the StoragePluginServiceServer interface for the
|
||||
// AWS storage service plugin.
|
||||
type StoragePlugin struct {
|
||||
@@ -42,6 +53,137 @@ type StoragePlugin struct {
|
||||
|
||||
// testStorageStateOpts are passed in to the stored state to control test behavior
|
||||
testStorageStateOpts []awsStoragePersistedStateOption
|
||||
|
||||
clients *clientCache
|
||||
}
|
||||
|
||||
// New creates a new StoragePlugin
|
||||
func New() *StoragePlugin {
|
||||
c := &clientCache{
|
||||
cache: make(map[string]S3API),
|
||||
}
|
||||
return &StoragePlugin{
|
||||
clients: c,
|
||||
}
|
||||
}
|
||||
|
||||
// getClient returns an S3API client for the given storage bucket id.
|
||||
func (p *StoragePlugin) getClient(ctx context.Context,
|
||||
storageBucketId string,
|
||||
storageState *awsStoragePersistedState,
|
||||
opt ...s3Option) (S3API, error) {
|
||||
if storageBucketId == "" {
|
||||
// No storage bucket ID to key cache on, create new client and return
|
||||
client, err := storageState.s3Client(ctx, opt...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error creating S3 client: %s", err)
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
opts, err := getOpts(opt...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing options in cache: %w", err)
|
||||
}
|
||||
|
||||
if opts.withCacheRefresh {
|
||||
// Forced cache refresh
|
||||
p.clients.Lock()
|
||||
defer p.clients.Unlock()
|
||||
client, err := storageState.s3Client(ctx, opt...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error creating S3 client: %s", err)
|
||||
}
|
||||
p.clients.cache[storageBucketId] = client
|
||||
return client, nil
|
||||
}
|
||||
|
||||
p.clients.RLock()
|
||||
client, ok := p.clients.cache[storageBucketId]
|
||||
p.clients.RUnlock()
|
||||
|
||||
if !ok || client.Credentials().Expired() {
|
||||
// We got a cache miss or the credentials has expired, time to refresh
|
||||
p.clients.Lock()
|
||||
defer p.clients.Unlock()
|
||||
|
||||
// Check cache again in case another caller updated it since we got the lock
|
||||
client, ok = p.clients.cache[storageBucketId]
|
||||
if ok && !client.Credentials().Expired() {
|
||||
// Got a cache hit with valid credentials, return cached client
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// Create new client and cache it
|
||||
var err error
|
||||
client, err = storageState.s3Client(ctx, opt...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error creating S3 client: %s", err)
|
||||
}
|
||||
p.clients.cache[storageBucketId] = client
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
type s3Caller func(client S3API) (any, error)
|
||||
|
||||
// call gets the s3client and passes it to the s3caller function, if a permission error is returned
|
||||
// it forces a cache refresh and tries again.
|
||||
func (p *StoragePlugin) call(
|
||||
ctx context.Context,
|
||||
fn s3Caller,
|
||||
storageBucketId string,
|
||||
storageState *awsStoragePersistedState,
|
||||
opts ...s3Option) (any, error) {
|
||||
|
||||
s3Client, err := p.getClient(ctx, storageBucketId, storageState, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error getting S3 client: %s", err)
|
||||
}
|
||||
firstAttempt := true
|
||||
for {
|
||||
resp, err := fn(s3Client)
|
||||
if err != nil {
|
||||
st, _ := errors.ParseAWSError("", err)
|
||||
if st.Code() == codes.PermissionDenied && firstAttempt {
|
||||
// We got a permission error, this is the first time so refresh cache and try again
|
||||
firstAttempt = false
|
||||
opts = append(opts, WithCacheRefresh(true))
|
||||
s3Client, err = p.getClient(ctx, storageBucketId, storageState, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error refreshing S3 client: %s", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NormalizeStorageBucketData is called by boundary before calling OnCreate or OnUpdate
|
||||
//
|
||||
// aws storage supports a total of 8 attributes, 6 as part of credential.CredentialAttributes
|
||||
// and 2 more from storage.StorageAttributes. of these, only endpoint_url is normalized.
|
||||
func (sp *StoragePlugin) NormalizeStorageBucketData(ctx context.Context, req *pb.NormalizeStorageBucketDataRequest) (*pb.NormalizeStorageBucketDataResponse, error) {
|
||||
sa, err := getStorageAttributes(req.GetAttributes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fields := req.GetAttributes().GetFields()
|
||||
if _, ok := fields[ConstAwsEndpointUrl]; ok {
|
||||
if sa.EndpointUrl, err = parseutil.NormalizeAddr(sa.EndpointUrl); err != nil {
|
||||
return nil, status.New(codes.InvalidArgument, fmt.Sprintf("failed to normalize provided %s: %s", ConstAwsEndpointUrl, err.Error())).Err()
|
||||
}
|
||||
fields[ConstAwsEndpointUrl] = structpb.NewStringValue(sa.EndpointUrl)
|
||||
}
|
||||
|
||||
return &pb.NormalizeStorageBucketDataResponse{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: fields,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// OnCreateStorageBucket is called when a storage bucket is created.
|
||||
@@ -102,7 +244,7 @@ func (p *StoragePlugin) OnCreateStorageBucket(ctx context.Context, req *pb.OnCre
|
||||
|
||||
persistedProto, err := storageState.toProto()
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus(err.Error())
|
||||
return nil, errors.BadRequestStatus("%s", err.Error())
|
||||
}
|
||||
|
||||
return &pb.OnCreateStorageBucketResponse{
|
||||
@@ -231,7 +373,7 @@ func (p *StoragePlugin) OnUpdateStorageBucket(ctx context.Context, req *pb.OnUpd
|
||||
|
||||
persistedProto, err := storageState.toProto()
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus(err.Error())
|
||||
return nil, errors.BadRequestStatus("%s", err.Error())
|
||||
}
|
||||
|
||||
return &pb.OnUpdateStorageBucketResponse{
|
||||
@@ -351,19 +493,20 @@ func (p *StoragePlugin) HeadObject(ctx context.Context, req *pb.HeadObjectReques
|
||||
if storageAttributes.DualStack {
|
||||
opts = append(opts, WithDualStack(storageAttributes.DualStack))
|
||||
}
|
||||
s3Client, err := storageState.S3Client(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error getting S3 client: %s", err)
|
||||
}
|
||||
|
||||
objectKey := path.Join(bucket.GetBucketPrefix(), req.GetKey())
|
||||
resp, err := s3Client.HeadObject(ctx, &s3.HeadObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(objectKey),
|
||||
})
|
||||
headCall := func(s3Client S3API) (any, error) {
|
||||
return s3Client.HeadObject(ctx, &s3.HeadObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(objectKey),
|
||||
})
|
||||
}
|
||||
headResp, err := p.call(ctx, headCall, bucket.GetId(), storageState, opts...)
|
||||
if err != nil {
|
||||
return nil, parseS3Error("head object", err, req).Err()
|
||||
}
|
||||
resp := headResp.(*s3.HeadObjectOutput)
|
||||
|
||||
return &pb.HeadObjectResponse{
|
||||
ContentLength: aws.ToInt64(resp.ContentLength),
|
||||
LastModified: timestamppb.New(*resp.LastModified),
|
||||
@@ -480,19 +623,19 @@ func (p *StoragePlugin) GetObject(req *pb.GetObjectRequest, stream pb.StoragePlu
|
||||
if storageAttributes.DualStack {
|
||||
opts = append(opts, WithDualStack(storageAttributes.DualStack))
|
||||
}
|
||||
s3Client, err := storageState.S3Client(stream.Context(), opts...)
|
||||
if err != nil {
|
||||
return errors.BadRequestStatus("error getting S3 client: %s", err)
|
||||
}
|
||||
|
||||
objectKey := path.Join(bucket.GetBucketPrefix(), req.GetKey())
|
||||
resp, err := s3Client.GetObject(stream.Context(), &s3.GetObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(objectKey),
|
||||
})
|
||||
getCall := func(s3Client S3API) (any, error) {
|
||||
return s3Client.GetObject(stream.Context(), &s3.GetObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(objectKey),
|
||||
})
|
||||
}
|
||||
getResp, err := p.call(stream.Context(), getCall, bucket.GetId(), storageState, opts...)
|
||||
if err != nil {
|
||||
return parseS3Error("get object", err, req).Err()
|
||||
}
|
||||
resp := getResp.(*s3.GetObjectOutput)
|
||||
|
||||
defer resp.Body.Close()
|
||||
reader := bufio.NewReader(resp.Body)
|
||||
@@ -594,10 +737,6 @@ func (p *StoragePlugin) PutObject(ctx context.Context, req *pb.PutObjectRequest)
|
||||
if storageAttributes.DualStack {
|
||||
opts = append(opts, WithDualStack(storageAttributes.DualStack))
|
||||
}
|
||||
s3Client, err := storageState.S3Client(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error getting S3 client: %s", err)
|
||||
}
|
||||
|
||||
hash := sha256.New()
|
||||
if _, err := io.Copy(hash, file); err != nil {
|
||||
@@ -609,18 +748,23 @@ func (p *StoragePlugin) PutObject(ctx context.Context, req *pb.PutObjectRequest)
|
||||
if err != nil {
|
||||
return nil, errors.UnknownStatus("failed to rewind file pointer")
|
||||
}
|
||||
|
||||
objectKey := path.Join(bucket.GetBucketPrefix(), req.GetKey())
|
||||
resp, err := s3Client.PutObject(ctx, &s3.PutObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(objectKey),
|
||||
Body: file,
|
||||
ChecksumAlgorithm: types.ChecksumAlgorithmSha256,
|
||||
ChecksumSHA256: aws.String(checksum),
|
||||
})
|
||||
|
||||
putCall := func(s3Client S3API) (any, error) {
|
||||
return s3Client.PutObject(ctx, &s3.PutObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(objectKey),
|
||||
Body: file,
|
||||
ChecksumAlgorithm: types.ChecksumAlgorithmSha256,
|
||||
ChecksumSHA256: aws.String(checksum),
|
||||
})
|
||||
}
|
||||
putResp, err := p.call(ctx, putCall, bucket.GetId(), storageState, opts...)
|
||||
if err != nil {
|
||||
return nil, parseS3Error("put object", err, req).Err()
|
||||
}
|
||||
resp := putResp.(*s3.PutObjectOutput)
|
||||
|
||||
if resp.ChecksumSHA256 == nil {
|
||||
return nil, errors.UnknownStatus("missing checksum response from aws")
|
||||
}
|
||||
@@ -689,10 +833,6 @@ func (p *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObjects
|
||||
if storageAttributes.EndpointUrl != "" {
|
||||
opts = append(opts, WithEndpoint(storageAttributes.EndpointUrl))
|
||||
}
|
||||
client, err := storageState.S3Client(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error getting S3 client: %s", err)
|
||||
}
|
||||
|
||||
prefix := path.Join(bucket.GetBucketPrefix(), req.GetKeyPrefix())
|
||||
if strings.HasSuffix(req.GetKeyPrefix(), "/") {
|
||||
@@ -702,10 +842,13 @@ func (p *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObjects
|
||||
}
|
||||
|
||||
if !req.Recursive {
|
||||
_, err := client.DeleteObject(ctx, &s3.DeleteObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(prefix),
|
||||
})
|
||||
deleteCall := func(s3Client S3API) (any, error) {
|
||||
return s3Client.DeleteObject(ctx, &s3.DeleteObjectInput{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
Key: aws.String(prefix),
|
||||
})
|
||||
}
|
||||
_, err := p.call(ctx, deleteCall, bucket.GetId(), storageState, opts...)
|
||||
if err != nil {
|
||||
return nil, parseS3Error("delete object", err, req).Err()
|
||||
}
|
||||
@@ -715,10 +858,13 @@ func (p *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObjects
|
||||
}
|
||||
|
||||
const maxkeys = 1000
|
||||
|
||||
objects := []types.ObjectIdentifier{}
|
||||
client, err := p.getClient(ctx, bucket.GetId(), storageState, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error getting S3 client: %s", err)
|
||||
}
|
||||
var conToken *string
|
||||
truncated := true
|
||||
truncated, firstAttempt := true, true
|
||||
for truncated {
|
||||
res, err := client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{
|
||||
Bucket: aws.String(bucket.GetBucketName()),
|
||||
@@ -727,6 +873,18 @@ func (p *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObjects
|
||||
ContinuationToken: conToken,
|
||||
})
|
||||
if err != nil {
|
||||
st, _ := errors.ParseAWSError("", err)
|
||||
if st.Code() == codes.PermissionDenied && firstAttempt {
|
||||
// This is first attempt and we get a permission error, refresh cache and try again
|
||||
firstAttempt = false
|
||||
opts = append(opts, WithCacheRefresh(true))
|
||||
client, err = p.getClient(ctx, bucket.GetId(), storageState, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error refreshing S3 client: %s", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
return nil, parseS3Error("list objects", err, req).Err()
|
||||
}
|
||||
truncated = aws.ToBool(res.IsTruncated)
|
||||
@@ -784,7 +942,7 @@ func dryRunValidation(ctx context.Context, state *awsStoragePersistedState, attr
|
||||
opts = append(opts, WithDualStack(attrs.DualStack))
|
||||
}
|
||||
|
||||
client, err := state.S3Client(ctx, opts...)
|
||||
client, err := state.s3Client(ctx, opts...)
|
||||
if err != nil {
|
||||
return status.New(codes.InvalidArgument, fmt.Sprintf("error getting S3 client: %s", err))
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/hashicorp/boundary-plugin-aws/internal/credential"
|
||||
internal "github.com/hashicorp/boundary-plugin-aws/internal/errors"
|
||||
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/storagebuckets"
|
||||
"github.com/hashicorp/boundary/sdk/pbs/plugin"
|
||||
pb "github.com/hashicorp/boundary/sdk/pbs/plugin"
|
||||
"github.com/hashicorp/go-secure-stdlib/awsutil/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -36,6 +37,204 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
func TestStoragePlugin_NormalizeStorageBucketData(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
req *plugin.NormalizeStorageBucketDataRequest
|
||||
expected *plugin.NormalizeStorageBucketDataResponse
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "missing attributes",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{},
|
||||
err: "attributes.region: missing required value \"region\"",
|
||||
},
|
||||
{
|
||||
name: "empty attributes",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{},
|
||||
},
|
||||
err: "attributes.region: missing required value \"region\"",
|
||||
},
|
||||
{
|
||||
name: "missing required field",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("http://127.0.0.1:9000"),
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "attributes.region: missing required value \"region\"",
|
||||
},
|
||||
{
|
||||
name: "missing endpoint_url",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &plugin.NormalizeStorageBucketDataResponse{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid endpoint_url returned unchanged",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("http://127.0.0.1:9000"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &plugin.NormalizeStorageBucketDataResponse{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("http://127.0.0.1:9000"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid ipv6 endpoint_url returned normalized",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("https://[2001:BEEF:0:0:0:1:0:0001]"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &plugin.NormalizeStorageBucketDataResponse{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("https://[2001:beef::1:0:1]"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid ipv6 endpoint_url with port returned normalized",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("https://[2001:BEEF:0:0:0:1:0:0001]:9000"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &plugin.NormalizeStorageBucketDataResponse{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("https://[2001:beef::1:0:1]:9000"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid ipv6 endpoint_url returns normalization error",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("https://[2001:BEEF:0:0:0:1:0:0001"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "failed to normalize provided endpoint_url: failed to parse address",
|
||||
},
|
||||
{
|
||||
name: "invalid ipv6 endpoint_url returns normalization error 2",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("https://[2001:BEEF:0:0:0:1:0:0001]:"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere"),
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "failed to normalize provided endpoint_url: url has malformed host: missing port value after colon",
|
||||
},
|
||||
{
|
||||
name: "valid all fields returns normalized",
|
||||
req: &plugin.NormalizeStorageBucketDataRequest{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("http://[2001:BEEF:0:0:0:1:0:0001]:9000/test/path"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere ❤"),
|
||||
credential.ConstDisableCredentialRotation: structpb.NewBoolValue(false),
|
||||
credential.ConstRoleArn: structpb.NewStringValue("an arn"),
|
||||
credential.ConstRoleExternalId: structpb.NewStringValue("id"),
|
||||
credential.ConstRoleSessionName: structpb.NewStringValue("sesh"),
|
||||
ConstAwsDualStack: structpb.NewBoolValue(false),
|
||||
credential.ConstRoleTags: structpb.NewStructValue(&structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"foo": structpb.NewStringValue("bar"),
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &plugin.NormalizeStorageBucketDataResponse{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
ConstAwsEndpointUrl: structpb.NewStringValue("http://[2001:beef::1:0:1]:9000/test/path"),
|
||||
credential.ConstRegion: structpb.NewStringValue("somewhere ❤"),
|
||||
credential.ConstDisableCredentialRotation: structpb.NewBoolValue(false),
|
||||
credential.ConstRoleArn: structpb.NewStringValue("an arn"),
|
||||
credential.ConstRoleExternalId: structpb.NewStringValue("id"),
|
||||
credential.ConstRoleSessionName: structpb.NewStringValue("sesh"),
|
||||
ConstAwsDualStack: structpb.NewBoolValue(false),
|
||||
credential.ConstRoleTags: structpb.NewStructValue(&structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"foo": structpb.NewStringValue("bar"),
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
sp := new(StoragePlugin)
|
||||
res, err := sp.NormalizeStorageBucketData(ctx, tt.req)
|
||||
|
||||
if tt.err != "" {
|
||||
require.ErrorContains(err, tt.err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
if st, ok := status.FromError(err); ok {
|
||||
require.Nil(err, st.Message())
|
||||
}
|
||||
}
|
||||
require.Nil(err)
|
||||
for key, val := range tt.expected.GetAttributes().GetFields() {
|
||||
v, ok := res.GetAttributes().GetFields()[key]
|
||||
assert.True(ok, "missing expected value: %q", key)
|
||||
if ok {
|
||||
assert.Equal(val, v, "expected[%q]: %v, but got: %v", key, val, v)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) {
|
||||
validRequest := func() *pb.OnCreateStorageBucketRequest {
|
||||
return &pb.OnCreateStorageBucketRequest{
|
||||
@@ -3917,3 +4116,89 @@ func TestStoragePlugin_DeleteObjects(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestS3ClientCache(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
cred1, err := awsutil.NewCredentialsConfig(
|
||||
awsutil.WithRegion("us-east-1"),
|
||||
awsutil.WithAccessKey("cred1"),
|
||||
awsutil.WithSecretKey("secret1"),
|
||||
)
|
||||
require.NoError(err)
|
||||
cred2, err := awsutil.NewCredentialsConfig(
|
||||
awsutil.WithRegion("us-east-1"),
|
||||
awsutil.WithAccessKey("cred2"),
|
||||
awsutil.WithSecretKey("secret2"),
|
||||
)
|
||||
require.NoError(err)
|
||||
cred3, err := awsutil.NewCredentialsConfig(
|
||||
awsutil.WithRegion("us-east-1"),
|
||||
awsutil.WithAccessKey("cred3"),
|
||||
awsutil.WithSecretKey("secret3"),
|
||||
)
|
||||
require.NoError(err)
|
||||
|
||||
p := New()
|
||||
cred, err := credential.NewAwsCredentialPersistedState(
|
||||
credential.WithCredentialsConfig(cred1),
|
||||
)
|
||||
require.NoError(err)
|
||||
|
||||
state, err := newAwsStoragePersistedState(withCredentials(cred))
|
||||
require.NoError(err)
|
||||
|
||||
// Cache should be empty before first call
|
||||
assert.Empty(p.clients.cache)
|
||||
|
||||
client, err := p.getClient(ctx, "id", state)
|
||||
require.NoError(err)
|
||||
require.NotNil(client)
|
||||
assert.Equal(cred1.AccessKey, client.Credentials().AccessKeyID)
|
||||
assert.Equal(cred1.SecretKey, client.Credentials().SecretAccessKey)
|
||||
|
||||
// Update state with new credentials
|
||||
cred, err = credential.NewAwsCredentialPersistedState(
|
||||
credential.WithCredentialsConfig(cred2),
|
||||
)
|
||||
require.NoError(err)
|
||||
state, err = newAwsStoragePersistedState(withCredentials(cred))
|
||||
require.NoError(err)
|
||||
|
||||
// Client is cached and creds valid so it should still grab initial client
|
||||
client, err = p.getClient(ctx, "id", state)
|
||||
require.NoError(err)
|
||||
require.NotNil(client)
|
||||
assert.Equal(cred1.AccessKey, client.Credentials().AccessKeyID)
|
||||
assert.Equal(cred1.SecretKey, client.Credentials().SecretAccessKey)
|
||||
|
||||
// Force credentials to expire
|
||||
c := client.(*s3Client)
|
||||
c.creds.CanExpire = true
|
||||
p.clients.Lock()
|
||||
p.clients.cache["id"] = c
|
||||
p.clients.Unlock()
|
||||
|
||||
// Getting client should now create new client on cred2 since the credentials have expired
|
||||
client, err = p.getClient(ctx, "id", state)
|
||||
require.NoError(err)
|
||||
require.NotNil(client)
|
||||
assert.Equal(cred2.AccessKey, client.Credentials().AccessKeyID)
|
||||
assert.Equal(cred2.SecretKey, client.Credentials().SecretAccessKey)
|
||||
|
||||
// Update state with new credentials again
|
||||
cred, err = credential.NewAwsCredentialPersistedState(
|
||||
credential.WithCredentialsConfig(cred3),
|
||||
)
|
||||
require.NoError(err)
|
||||
state, err = newAwsStoragePersistedState(withCredentials(cred))
|
||||
require.NoError(err)
|
||||
|
||||
// Getting client and force cache refresh should return cred3 based client
|
||||
client, err = p.getClient(ctx, "id", state, WithCacheRefresh(true))
|
||||
require.NoError(err)
|
||||
require.NotNil(client)
|
||||
assert.Equal(cred3.AccessKey, client.Credentials().AccessKeyID)
|
||||
assert.Equal(cred3.SecretKey, client.Credentials().SecretAccessKey)
|
||||
}
|
||||
@@ -24,6 +24,16 @@ type S3API interface {
|
||||
PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error)
|
||||
DeleteObjects(ctx context.Context, params *s3.DeleteObjectsInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectsOutput, error)
|
||||
ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error)
|
||||
Credentials() aws.Credentials
|
||||
}
|
||||
|
||||
type s3Client struct {
|
||||
*s3.Client
|
||||
creds aws.Credentials
|
||||
}
|
||||
|
||||
func (c *s3Client) Credentials() aws.Credentials {
|
||||
return c.creds
|
||||
}
|
||||
|
||||
type awsStoragePersistedState struct {
|
||||
@@ -77,9 +87,9 @@ func (s *awsStoragePersistedState) toProto() (*storagebuckets.StorageBucketPersi
|
||||
return &storagebuckets.StorageBucketPersisted{Data: data}, nil
|
||||
}
|
||||
|
||||
// S3Client returns a configured S3 client based on the session
|
||||
// s3Client returns a configured S3 client based on the session
|
||||
// information stored in the state.
|
||||
func (s *awsStoragePersistedState) S3Client(ctx context.Context, opt ...s3Option) (S3API, error) {
|
||||
func (s *awsStoragePersistedState) s3Client(ctx context.Context, opt ...s3Option) (S3API, error) {
|
||||
opts, err := getOpts(opt...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing options when fetching S3 client: %w", err)
|
||||
@@ -101,7 +111,16 @@ func (s *awsStoragePersistedState) S3Client(ctx context.Context, opt ...s3Option
|
||||
if s.testS3APIFunc != nil {
|
||||
return s.testS3APIFunc(*awsCfg)
|
||||
}
|
||||
return s3.NewFromConfig(*awsCfg, s3Opts...), nil
|
||||
|
||||
// Retrieve the credentials provider from the client
|
||||
credsProvider := awsCfg.Credentials
|
||||
creds, err := credsProvider.Retrieve(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve credentials: %v\n", err)
|
||||
}
|
||||
|
||||
c := s3.NewFromConfig(*awsCfg, s3Opts...)
|
||||
return &s3Client{Client: c, creds: creds}, nil
|
||||
}
|
||||
|
||||
// getOpts iterates the inbound s3Options and returns a struct
|
||||
@@ -123,14 +142,23 @@ type s3Option func(*s3Options) error
|
||||
|
||||
// options = how options are represented
|
||||
type s3Options struct {
|
||||
withEndpoint string
|
||||
withDualStack bool
|
||||
withEndpoint string
|
||||
withDualStack bool
|
||||
withCacheRefresh bool
|
||||
}
|
||||
|
||||
func getDefaultS3Options() s3Options {
|
||||
return s3Options{}
|
||||
}
|
||||
|
||||
// WithCacheRefresh controls if the cache should be forced to refresh
|
||||
func WithCacheRefresh(refresh bool) s3Option {
|
||||
return func(o *s3Options) error {
|
||||
o.withCacheRefresh = refresh
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithEndpoint contains the endpoint to use
|
||||
func WithEndpoint(with string) s3Option {
|
||||
return func(o *s3Options) error {
|
||||
|
||||
@@ -64,7 +64,7 @@ func TestAwsStoragePersistedStateS3Client(t *testing.T) {
|
||||
)
|
||||
require.NoError(err)
|
||||
|
||||
clientRaw, err := state.S3Client(context.Background(), tc.s3Opts...)
|
||||
clientRaw, err := state.s3Client(context.Background(), tc.s3Opts...)
|
||||
require.NoError(err)
|
||||
require.NotNil(clientRaw)
|
||||
client, ok := clientRaw.(*testMockS3)
|
||||
|
||||
Reference in new issue
Block a user