vendor: run make vendor-update

This commit is contained in:
Aliaksandr Valialkin 2023-11-14 22:45:07 +01:00
parent 3076c1f400
commit 201fb6ec5c
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
59 changed files with 996 additions and 15227 deletions

14
go.mod
View file

@ -17,8 +17,8 @@ require (
github.com/VictoriaMetrics/metrics v1.24.0
github.com/VictoriaMetrics/metricsql v0.69.0
github.com/aws/aws-sdk-go-v2 v1.22.2
github.com/aws/aws-sdk-go-v2/config v1.23.0
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.5
github.com/aws/aws-sdk-go-v2/config v1.25.0
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.7
github.com/aws/aws-sdk-go-v2/service/s3 v1.42.1
github.com/bmatcuk/doublestar/v4 v4.6.1
github.com/cespare/xxhash/v2 v2.2.0
@ -53,13 +53,13 @@ require (
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/aws/aws-sdk-go v1.47.9 // indirect
github.com/aws/aws-sdk-go v1.47.11 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.0 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.15.2 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.0 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.6.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.2 // indirect
@ -112,8 +112,8 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/collector/pdata v1.0.0-rcv0017 // indirect
go.opentelemetry.io/collector/semconv v0.88.0 // indirect
go.opentelemetry.io/collector/pdata v1.0.0-rcv0018 // indirect
go.opentelemetry.io/collector/semconv v0.89.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 // indirect
go.opentelemetry.io/otel v1.20.0 // indirect
go.opentelemetry.io/otel/metric v1.20.0 // indirect

28
go.sum
View file

@ -85,26 +85,26 @@ github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.47.9 h1:rarTsos0mA16q+huicGx0e560aYRtOucV5z2Mw23JRY=
github.com/aws/aws-sdk-go v1.47.9/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go v1.47.11 h1:Dol+MA+hQblbnXUI3Vk9qvoekU6O1uDEuAItezjiWNQ=
github.com/aws/aws-sdk-go v1.47.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.22.2 h1:lV0U8fnhAnPz8YcdmZVV60+tr6CakHzqA6P8T46ExJI=
github.com/aws/aws-sdk-go-v2 v1.22.2/go.mod h1:Kd0OJtkW3Q0M0lUWGszapWjEvrXDzRW+D21JNsroB+c=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.0 h1:hHgLiIrTRtddC0AKcJr5s7i/hLgcpTt+q/FKxf1Zayk=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.0/go.mod h1:w4I/v3NOWgD+qvs1NPEwhd++1h3XPHFaVxasfY6HlYQ=
github.com/aws/aws-sdk-go-v2/config v1.23.0 h1:kqzEfGGDIrRJpfJckgwuZfFTbU9NB1jZnRcaO9MpOqE=
github.com/aws/aws-sdk-go-v2/config v1.23.0/go.mod h1:p7wbxKXXjS1GGQOss7VXOazVMFF9bjUGq85/4wR/fSw=
github.com/aws/aws-sdk-go-v2/credentials v1.15.2 h1:rKH7khRMxPdD0u3dHecd0Q7NOVw3EUe7AqdkUOkiOGI=
github.com/aws/aws-sdk-go-v2/credentials v1.15.2/go.mod h1:tXM8wmaeAhfC7nZoCxb0FzM/aRaB1m1WQ7x0qlBLq80=
github.com/aws/aws-sdk-go-v2/config v1.25.0 h1:WCwAqyrM/kqYi6pHjVpq/w2pLydeGKv8Af9vdtO3ciM=
github.com/aws/aws-sdk-go-v2/config v1.25.0/go.mod h1:1QMnmhoWcR6957nC1MUUhhOLx9NOGFSVNG3Mag9vLU4=
github.com/aws/aws-sdk-go-v2/credentials v1.16.0 h1:sSEHkXonpZBSPcyUBDRlZjxOi14qM/UK7/vfKhGwmTo=
github.com/aws/aws-sdk-go-v2/credentials v1.16.0/go.mod h1:tXM8wmaeAhfC7nZoCxb0FzM/aRaB1m1WQ7x0qlBLq80=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.3 h1:G5KawTAkyHH6WyKQCdHiW4h3PmAXNJpOgwKg3H7sDRE=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.3/go.mod h1:hugKmSFnZB+HgNI1sYGT14BUPZkO6alC/e0AWu+0IAQ=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.5 h1:P/xwilRdRLLg1PzfviDq0Zjb74weOoDCrh8J5lRCQAY=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.5/go.mod h1:9cLHf2IwX6Jyw0KjLVbXly/g6DmzExgUzB1w/AQPGQE=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.7 h1:HDsYN1Qm6fFDKzaGfYVGGBNkifZAHWVBrzrILGhpdIU=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.7/go.mod h1:998wVfFSQY1hGhRXfv6QYGY08qi/L7Apr1XmJSWS5YI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.2 h1:AaQsr5vvGR7rmeSWBtTCcw16tT9r51mWijuCQhzLnq8=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.2/go.mod h1:o1IiRn7CWocIFTXJjGKJDOwxv1ibL53NpcvcqGWyRBA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.2 h1:UZx8SXZ0YtzRiALzYAWcjb9Y9hZUR7MBKaBQ5ouOjPs=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.2/go.mod h1:ipuRpcSaklmxR6C39G187TpBAO132gUfleTGccUPs8c=
github.com/aws/aws-sdk-go-v2/internal/ini v1.6.0 h1:hwZB07/beLiCopuRKF0t+dEHmP39iN4YtDh3X5d3hrg=
github.com/aws/aws-sdk-go-v2/internal/ini v1.6.0/go.mod h1:rdAuXeHWhI/zkpYcO5n8WCpaIgY9MUxFyBsuqq3kjyA=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.0 h1:usgqiJtamuGIBj+OvYmMq89+Z1hIKkMJToz1WpoeNUY=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.0/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.2 h1:pyVrNAf7Hwz0u39dLKN5t+n0+K/3rMYKuiOoIum3AsU=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.2/go.mod h1:mydrfOb9uiOYCxuCPR8YHQNQyGQwUQ7gPMZGBKbH8NY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.0 h1:CJxo7ZBbaIzmXfV3hjcx36n9V87gJsIUPJflwqEHl3Q=
@ -457,10 +457,10 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/collector/pdata v1.0.0-rcv0017 h1:AgALhc2VenoA5l1DvTdg7mkzaBGqoTSuMkAtjsttBFo=
go.opentelemetry.io/collector/pdata v1.0.0-rcv0017/go.mod h1:Rv9fOclA5AtM/JGm0d4jBOIAo1+jBA13UT5Bx0ovXi4=
go.opentelemetry.io/collector/semconv v0.88.0 h1:8TVP4hYaUC87S6CCLKNoSxsUE0ChldE4vqotvNHHUnE=
go.opentelemetry.io/collector/semconv v0.88.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw=
go.opentelemetry.io/collector/pdata v1.0.0-rcv0018 h1:a2IHOZKphRzPagcvOHQHHUE0DlITFSKlIBwaWhPZpl4=
go.opentelemetry.io/collector/pdata v1.0.0-rcv0018/go.mod h1:oNIcTRyEJYIfMcRYyyh5lquDU0Vl+ktTL6ka+p+dYvg=
go.opentelemetry.io/collector/semconv v0.89.0 h1:Sw+MiI3/oiYIY+ebkanZsOaBxXMx3sqnH1/6NaD4rLQ=
go.opentelemetry.io/collector/semconv v0.89.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 h1:1eHu3/pUSWaOgltNK3WJFaywKsTIr/PwvHyDmi0lQA0=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0/go.mod h1:HyABWq60Uy1kjJSa2BVOxUVao8Cdick5AWSKPutqy6U=
go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=

View file

@ -1,14 +0,0 @@
dist
/doc
/doc-staging
.yardoc
Gemfile.lock
/internal/awstesting/integration/smoke/**/importmarker__.go
/internal/awstesting/integration/smoke/_test/
/vendor
/private/model/cli/gen-api/gen-api
.gradle/
build/
.idea/
bin/
.vscode/

View file

@ -1,27 +0,0 @@
[run]
concurrency = 4
timeout = "1m"
issues-exit-code = 0
modules-download-mode = "readonly"
allow-parallel-runners = true
skip-dirs = ["internal/repotools"]
skip-dirs-use-default = true
skip-files = ["service/transcribestreaming/eventstream_test.go"]
[output]
format = "github-actions"
[linters-settings.cyclop]
skip-tests = false
[linters-settings.errcheck]
check-blank = true
[linters]
disable-all = true
enable = ["errcheck"]
fast = false
[issues]
exclude-use-default = false
# Refer config definitions at https://golangci-lint.run/usage/configuration/#config-file

View file

@ -1,31 +0,0 @@
language: go
sudo: true
dist: bionic
branches:
only:
- main
os:
- linux
- osx
# Travis doesn't work with windows and Go tip
#- windows
go:
- tip
matrix:
allow_failures:
- go: tip
before_install:
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then choco install make; fi
- (cd /tmp/; go get golang.org/x/lint/golint)
env:
- EACHMODULE_CONCURRENCY=4
script:
- make ci-test-no-generate;

File diff suppressed because it is too large Load diff

View file

@ -1,4 +0,0 @@
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.

View file

@ -1,177 +0,0 @@
# Contributing to the AWS SDK for Go
Thank you for your interest in contributing to the AWS SDK for Go!
We work hard to provide a high-quality and useful SDK, and we greatly value
feedback and contributions from our community. Whether it's a bug report,
new feature, correction, or additional documentation, we welcome your issues
and pull requests. Please read through this document before submitting any
[issues] or [pull requests][pr] to ensure we have all the necessary information to
effectively respond to your bug report or contribution.
Jump To:
* [Bug Reports](#bug-reports)
* [Feature Requests](#feature-requests)
* [Code Contributions](#code-contributions)
## How to contribute
*Before you send us a pull request, please be sure that:*
1. You're working from the latest source on the `main` branch.
2. You check existing open, and recently closed, pull requests to be sure
that someone else hasn't already addressed the problem.
3. You create an issue before working on a contribution that will take a
significant amount of your time.
*Creating a Pull Request*
1. Fork the repository.
2. In your fork, make your change in a branch that's based on this repo's `main` branch.
3. Commit the change to your fork, using a clear and descriptive commit message.
4. Create a pull request, answering any questions in the pull request form.
For contributions that will take a significant amount of time, open a new
issue to pitch your idea before you get started. Explain the problem and
describe the content you want to see added to the documentation. Let us know
if you'll write it yourself or if you'd like us to help. We'll discuss your
proposal with you and let you know whether we're likely to accept it.
## Bug Reports
You can file bug reports against the SDK on the [GitHub issues][issues] page.
If you are filing a report for a bug or regression in the SDK, it's extremely
helpful to provide as much information as possible when opening the original
issue. This helps us reproduce and investigate the possible bug without having
to wait for this extra information to be provided. Please read the following
guidelines prior to filing a bug report.
1. Search through existing [issues][] to ensure that your specific issue has
not yet been reported. If it is a common issue, it is likely there is
already a bug report for your problem.
2. Ensure that you have tested the latest version of the SDK. Although you
may have an issue against an older version of the SDK, we cannot provide
bug fixes for old versions. It's also possible that the bug may have been
fixed in the latest release.
3. Provide as much information about your environment, SDK version, and
relevant dependencies as possible. For example, let us know what version
of Go you are using, which and version of the operating system, and the
the environment your code is running in. e.g Container.
4. Provide a minimal test case that reproduces your issue or any error
information you related to your problem. We can provide feedback much
more quickly if we know what operations you are calling in the SDK. If
you cannot provide a full test case, provide as much code as you can
to help us diagnose the problem. Any relevant information should be provided
as well, like whether this is a persistent issue, or if it only occurs
some of the time.
## Feature Requests
Open an [issue][issues] with the following:
* A short, descriptive title. Ideally, other community members should be able
to get a good idea of the feature just from reading the title.
* A detailed description of the the proposed feature.
* Why it should be added to the SDK.
* If possible, example code to illustrate how it should work.
* Use Markdown to make the request easier to read;
* If you intend to implement this feature, indicate that you'd like to the issue to be assigned to you.
## Code Contributions
We are always happy to receive code and documentation contributions to the SDK.
Please be aware of the following notes prior to opening a pull request:
1. The SDK is released under the [Apache license][license]. Any code you submit
will be released under that license. For substantial contributions, we may
ask you to sign a [Contributor License Agreement (CLA)][cla].
2. If you would like to implement support for a significant feature that is not
yet available in the SDK, please talk to us beforehand to avoid any
duplication of effort.
3. Wherever possible, pull requests should contain tests as appropriate.
Bugfixes should contain tests that exercise the corrected behavior (i.e., the
test should fail without the bugfix and pass with it), and new features
should be accompanied by tests exercising the feature.
4. Pull requests that contain failing tests will not be merged until the test
failures are addressed. Pull requests that cause a significant drop in the
SDK's test coverage percentage are unlikely to be merged until tests have
been added.
5. The JSON files under the SDK's `models` folder are sourced from outside the SDK.
Such as `models/apis/ec2/2016-11-15/api.json`. We will not accept pull requests
directly on these models. If you discover an issue with the models please
create a [GitHub issue][issues] describing the issue.
### Testing
To run the tests locally, running the `make unit` command will `go get` the
SDK's testing dependencies, and run vet, link and unit tests for the SDK.
```
make unit
```
Standard go testing functionality is supported as well. To test SDK code that
is tagged with `codegen` you'll need to set the build tag in the go test
command. The `make unit` command will do this automatically.
```
go test -tags codegen ./private/...
```
See the `Makefile` for additional testing tags that can be used in testing.
To test on multiple platform the SDK includes several DockerFiles under the
`awstesting/sandbox` folder, and associated make recipes to to execute
unit testing within environments configured for specific Go versions.
```
make sandbox-test-go18
```
To run all sandbox environments use the following make recipe
```
# Optionally update the Go tip that will be used during the batch testing
make update-aws-golang-tip
# Run all SDK tests for supported Go versions in sandboxes
make sandbox-test
```
In addition the sandbox environment include make recipes for interactive modes
so you can run command within the Docker container and context of the SDK.
```
make sandbox-go18
```
### Changelog Documents
You can see all release changes in the `CHANGELOG.md` file at the root of the
repository. The release notes added to this file will contain service client
updates, and major SDK changes. When submitting a pull request please include an entry in `CHANGELOG_PENDING.md` under the appropriate changelog type so your changelog entry is included on the following release.
#### Changelog Types
* `SDK Features` - For major additive features, internal changes that have
outward impact, or updates to the SDK foundations. This will result in a minor
version change.
* `SDK Enhancements` - For minor additive features or incremental sized changes.
This will result in a patch version change.
* `SDK Bugs` - For minor changes that resolve an issue. This will result in a
patch version change.
[issues]: https://github.com/aws/aws-sdk-go-v2/issues
[pr]: https://github.com/aws/aws-sdk-go-v2/pulls
[license]: http://aws.amazon.com/apache2.0/
[cla]: http://en.wikipedia.org/wiki/Contributor_License_Agreement
[releasenotes]: https://github.com/aws/aws-sdk-go-v2/releases

View file

@ -1,15 +0,0 @@
Open Discussions
---
The following issues are currently open for community feedback.
All discourse must adhere to the [Code of Conduct] policy.
* [Refactoring API Client Paginators](https://github.com/aws/aws-sdk-go-v2/issues/439)
* [Refactoring API Client Waiters](https://github.com/aws/aws-sdk-go-v2/issues/442)
* [Refactoring API Client Enums and Types to Discrete Packages](https://github.com/aws/aws-sdk-go-v2/issues/445)
* [SDK Modularization](https://github.com/aws/aws-sdk-go-v2/issues/444)
Past Discussions
---
The issues listed here are for documentation purposes, and is used to capture issues and their associated discussions.
[Code of Conduct]: https://github.com/aws/aws-sdk-go-v2/blob/main/CODE_OF_CONDUCT.md

View file

@ -1,538 +0,0 @@
# Lint rules to ignore
LINTIGNORESINGLEFIGHT='internal/sync/singleflight/singleflight.go:.+error should be the last type'
LINT_IGNORE_S3MANAGER_INPUT='feature/s3/manager/upload.go:.+struct field SSEKMSKeyId should be SSEKMSKeyID'
# Names of these are tied to endpoint rules and they're internal so ignore them
LINT_IGNORE_AWSRULESFN_ARN='internal/endpoints/awsrulesfn/arn.go'
LINT_IGNORE_AWSRULESFN_PARTITION='internal/endpoints/awsrulesfn/partition.go'
UNIT_TEST_TAGS=
BUILD_TAGS=-tags "example,codegen,integration,ec2env,perftest"
SMITHY_GO_SRC ?= $(shell pwd)/../smithy-go
SDK_MIN_GO_VERSION ?= 1.19
EACHMODULE_FAILFAST ?= true
EACHMODULE_FAILFAST_FLAG=-fail-fast=${EACHMODULE_FAILFAST}
EACHMODULE_CONCURRENCY ?= 1
EACHMODULE_CONCURRENCY_FLAG=-c ${EACHMODULE_CONCURRENCY}
EACHMODULE_SKIP ?=
EACHMODULE_SKIP_FLAG=-skip="${EACHMODULE_SKIP}"
EACHMODULE_FLAGS=${EACHMODULE_CONCURRENCY_FLAG} ${EACHMODULE_FAILFAST_FLAG} ${EACHMODULE_SKIP_FLAG}
# SDK's Core and client packages that are compatible with Go 1.9+.
SDK_CORE_PKGS=./aws/... ./internal/...
SDK_CLIENT_PKGS=./service/...
SDK_COMPA_PKGS=${SDK_CORE_PKGS} ${SDK_CLIENT_PKGS}
# SDK additional packages that are used for development of the SDK.
SDK_EXAMPLES_PKGS=
SDK_ALL_PKGS=${SDK_COMPA_PKGS} ${SDK_EXAMPLES_PKGS}
RUN_NONE=-run NONE
RUN_INTEG=-run '^TestInteg_'
CODEGEN_RESOURCES_PATH=$(shell pwd)/codegen/smithy-aws-go-codegen/src/main/resources/software/amazon/smithy/aws/go/codegen
CODEGEN_API_MODELS_PATH=$(shell pwd)/codegen/sdk-codegen/aws-models
ENDPOINTS_JSON=${CODEGEN_RESOURCES_PATH}/endpoints.json
ENDPOINT_PREFIX_JSON=${CODEGEN_RESOURCES_PATH}/endpoint-prefix.json
LICENSE_FILE=$(shell pwd)/LICENSE.txt
SMITHY_GO_VERSION ?=
PRE_RELEASE_VERSION ?=
RELEASE_MANIFEST_FILE ?=
RELEASE_CHGLOG_DESC_FILE ?=
REPOTOOLS_VERSION ?= latest
REPOTOOLS_MODULE = github.com/awslabs/aws-go-multi-module-repository-tools
REPOTOOLS_CMD_ANNOTATE_STABLE_GEN = ${REPOTOOLS_MODULE}/cmd/annotatestablegen@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_MAKE_RELATIVE = ${REPOTOOLS_MODULE}/cmd/makerelative@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_CALCULATE_RELEASE = ${REPOTOOLS_MODULE}/cmd/calculaterelease@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_UPDATE_REQUIRES = ${REPOTOOLS_MODULE}/cmd/updaterequires@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_UPDATE_MODULE_METADATA = ${REPOTOOLS_MODULE}/cmd/updatemodulemeta@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_GENERATE_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/generatechangelog@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_TAG_RELEASE = ${REPOTOOLS_MODULE}/cmd/tagrelease@${REPOTOOLS_VERSION}
REPOTOOLS_CMD_EDIT_MODULE_DEPENDENCY = ${REPOTOOLS_MODULE}/cmd/editmoduledependency@${REPOTOOLS_VERSION}
REPOTOOLS_CALCULATE_RELEASE_VERBOSE ?= false
REPOTOOLS_CALCULATE_RELEASE_VERBOSE_FLAG=-v=${REPOTOOLS_CALCULATE_RELEASE_VERBOSE}
REPOTOOLS_CALCULATE_RELEASE_ADDITIONAL_ARGS ?=
ifneq ($(PRE_RELEASE_VERSION),)
REPOTOOLS_CALCULATE_RELEASE_ADDITIONAL_ARGS += -preview=${PRE_RELEASE_VERSION}
endif
.PHONY: all
all: generate unit
###################
# Code Generation #
###################
.PHONY: generate smithy-generate smithy-build smithy-build-% smithy-clean smithy-go-publish-local format \
gen-config-asserts gen-repo-mod-replace gen-mod-replace-smithy gen-mod-dropreplace-smithy-% gen-aws-ptrs tidy-modules-% \
add-module-license-files sync-models sync-endpoints-model sync-endpoints.json clone-v1-models gen-internal-codegen \
sync-api-models copy-attributevalue-feature min-go-version-% update-requires smithy-annotate-stable \
update-module-metadata download-modules-%
generate: smithy-generate update-requires gen-repo-mod-replace update-module-metadata smithy-annotate-stable \
gen-config-asserts gen-internal-codegen copy-attributevalue-feature gen-mod-dropreplace-smithy-. min-go-version-. \
tidy-modules-. add-module-license-files gen-aws-ptrs format
generate-tmpreplace-smithy: smithy-generate update-requires gen-repo-mod-replace update-module-metadata smithy-annotate-stable \
gen-config-asserts gen-internal-codegen copy-attributevalue-feature gen-mod-replace-smithy-. min-go-version-. \
tidy-modules-. add-module-license-files gen-aws-ptrs format gen-mod-dropreplace-smithy-. reset-sum
reset-sum:
find . -name go.sum -exec git checkout -- {} \;
smithy-generate:
cd codegen && ./gradlew clean build -Plog-tests && ./gradlew clean
smithy-build:
cd codegen && ./gradlew clean build -Plog-tests
smithy-build-%:
@# smithy-build- command that uses the pattern to define build filter that
@# the smithy API model service id starts with. Strips off the
@# "smithy-build-".
@#
@# e.g. smithy-build-com.amazonaws.rds
@# e.g. smithy-build-com.amazonaws.rds#AmazonRDSv19
cd codegen && \
SMITHY_GO_BUILD_API="$(subst smithy-build-,,$@)" ./gradlew clean build -Plog-tests
smithy-annotate-stable:
go run ${REPOTOOLS_CMD_ANNOTATE_STABLE_GEN}
smithy-clean:
cd codegen && ./gradlew clean
smithy-go-publish-local:
rm -rf /tmp/smithy-go-local
git clone https://github.com/aws/smithy-go /tmp/smithy-go-local
make -C /tmp/smithy-go-local smithy-clean smithy-publish-local
format:
gofmt -w -s .
gen-config-asserts:
@echo "Generating SDK config package implementor assertions"
cd config \
&& go mod tidy \
&& go generate
gen-internal-codegen:
@echo "Generating internal/codegen"
cd internal/codegen \
&& go mod tidy \
&& go generate
gen-repo-mod-replace:
@echo "Generating go.mod replace for repo modules"
go run ${REPOTOOLS_CMD_MAKE_RELATIVE}
gen-mod-replace-smithy-%:
@# gen-mod-replace-smithy- command that uses the pattern to define build filter that
@# for modules to add replace to. Strips off the "gen-mod-replace-smithy-".
@#
@# SMITHY_GO_SRC environment variable is the path to add replace to
@#
@# e.g. gen-mod-replace-smithy-service_ssooidc
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst gen-mod-replace-smithy-,,$@)) ${EACHMODULE_FLAGS} \
"go mod edit -replace github.com/aws/smithy-go=${SMITHY_GO_SRC}"
gen-mod-dropreplace-smithy-%:
@# gen-mod-dropreplace-smithy- command that uses the pattern to define build filter that
@# for modules to add replace to. Strips off the "gen-mod-dropreplace-smithy-".
@#
@# e.g. gen-mod-dropreplace-smithy-service_ssooidc
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst gen-mod-dropreplace-smithy-,,$@)) ${EACHMODULE_FLAGS} \
"go mod edit -dropreplace github.com/aws/smithy-go"
gen-aws-ptrs:
cd aws && go generate
tidy-modules-%:
@# tidy command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "tidy-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. tidy-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst tidy-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go mod tidy"
download-modules-%:
@# download command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "download-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. download-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst download-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go mod download all"
add-module-license-files:
cd internal/repotools/cmd/eachmodule && \
go run . -skip-root \
"cp $(LICENSE_FILE) ."
sync-models: sync-endpoints-model sync-api-models
sync-endpoints-model: sync-endpoints.json
sync-endpoints.json:
[[ ! -z "${ENDPOINTS_MODEL}" ]] && cp ${ENDPOINTS_MODEL} ${ENDPOINTS_JSON} || echo "ENDPOINTS_MODEL not set, must not be empty"
clone-v1-models:
rm -rf /tmp/aws-sdk-go-model-sync
git clone https://github.com/aws/aws-sdk-go.git --depth 1 /tmp/aws-sdk-go-model-sync
sync-api-models:
cd internal/repotools/cmd/syncAPIModels && \
go run . \
-m ${API_MODELS} \
-o ${CODEGEN_API_MODELS_PATH}
copy-attributevalue-feature:
cd ./feature/dynamodbstreams/attributevalue && \
find . -name "*.go" | grep -v "doc.go" | xargs -I % rm % && \
find ../../dynamodb/attributevalue -name "*.go" | grep -v "doc.go" | xargs -I % cp % . && \
ls *.go | grep -v "convert.go" | grep -v "doc.go" | \
xargs -I % sed -i.bk -E 's:github.com/aws/aws-sdk-go-v2/(service|feature)/dynamodb:github.com/aws/aws-sdk-go-v2/\1/dynamodbstreams:g' % && \
ls *.go | grep -v "convert.go" | grep -v "doc.go" | \
xargs -I % sed -i.bk 's:DynamoDB:DynamoDBStreams:g' % && \
ls *.go | grep -v "doc.go" | \
xargs -I % sed -i.bk 's:dynamodb\.:dynamodbstreams.:g' % && \
sed -i.bk 's:streams\.:ddbtypes.:g' "convert.go" && \
sed -i.bk 's:ddb\.:streams.:g' "convert.go" && \
sed -i.bk 's:ddbtypes\.:ddb.:g' "convert.go" &&\
sed -i.bk 's:Streams::g' "convert.go" && \
rm -rf ./*.bk && \
go mod tidy && \
gofmt -w -s . && \
go test .
min-go-version-%:
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst min-go-version-,,$@)) ${EACHMODULE_FLAGS} \
"go mod edit -go=${SDK_MIN_GO_VERSION}"
update-requires:
go run ${REPOTOOLS_CMD_UPDATE_REQUIRES}
update-module-metadata:
go run ${REPOTOOLS_CMD_UPDATE_MODULE_METADATA}
################
# Unit Testing #
################
.PHONY: unit unit-race unit-test unit-race-test unit-race-modules-% unit-modules-% build build-modules-% \
go-build-modules-% test test-race-modules-% test-modules-% cachedep cachedep-modules-% api-diff-modules-%
unit: lint unit-modules-.
unit-race: lint unit-race-modules-.
unit-test: test-modules-.
unit-race-test: test-race-modules-.
unit-race-modules-%:
@# unit command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "unit-race-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. unit-race-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst unit-race-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go vet ${BUILD_TAGS} --all ./..." \
"go test ${BUILD_TAGS} ${RUN_NONE} ./..." \
"go test -timeout=2m ${UNIT_TEST_TAGS} -race -cpu=4 ./..."
unit-modules-%:
@# unit command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "unit-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. unit-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst unit-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go vet ${BUILD_TAGS} --all ./..." \
"go test ${BUILD_TAGS} ${RUN_NONE} ./..." \
"go test -timeout=2m ${UNIT_TEST_TAGS} ./..."
build: build-modules-.
build-modules-%:
@# build command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "build-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. build-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst build-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go test ${BUILD_TAGS} ${RUN_NONE} ./..."
go-build-modules-%:
@# build command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "build-modules-" and
@# replaces all "_" with "/".
@#
@# Validates that all modules in the repo have buildable Go files.
@#
@# e.g. go-build-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst go-build-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go build ${BUILD_TAGS} ./..."
test: test-modules-.
test-race-modules-%:
@# Test command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "test-race-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. test-race-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst test-race-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go test -timeout=2m ${UNIT_TEST_TAGS} -race -cpu=4 ./..."
test-modules-%:
@# Test command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "test-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. test-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst test-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go test -timeout=2m ${UNIT_TEST_TAGS} ./..."
cachedep: cachedep-modules-.
cachedep-modules-%:
@# build command that uses the pattern to define the root path that the
@# module caching will start from. Strips off the "cachedep-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. cachedep-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst cachedep-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go mod download"
api-diff-modules-%:
@# Command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "api-diff-modules-" and
@# replaces all "_" with "/".
@#
@# Requires golang.org/x/exp/cmd/gorelease to be available in the GOPATH.
@#
@# e.g. api-diff-modules-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst api-diff-modules-,,$@)) \
-fail-fast=true \
-c 1 \
-skip="internal/repotools" \
"$$(go env GOPATH)/bin/gorelease"
##############
# CI Testing #
##############
.PHONY: ci-test ci-test-no-generate ci-test-generate-validate
ci-test: generate unit-race ci-test-generate-validate
ci-test-no-generate: unit-race
ci-test-generate-validate:
@echo "CI test validate no generated code changes"
git update-index --assume-unchanged go.mod go.sum
git add . -A
gitstatus=`git diff --cached --ignore-space-change`; \
echo "$$gitstatus"; \
if [ "$$gitstatus" != "" ] && [ "$$gitstatus" != "skipping validation" ]; then echo "$$gitstatus"; exit 1; fi
git update-index --no-assume-unchanged go.mod go.sum
ci-lint: ci-lint-.
ci-lint-%:
@# Run golangci-lint command that uses the pattern to define the root path that the
@# module check will start from. Strips off the "ci-lint-" and
@# replaces all "_" with "/".
@#
@# e.g. ci-lint-internal_protocoltest
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst ci-lint-,,$@)) \
-fail-fast=false \
-c 1 \
-skip="internal/repotools" \
"golangci-lint run"
ci-lint-install:
@# Installs golangci-lint at GoPATH.
@# This should be used to run golangci-lint locally.
@#
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
#######################
# Integration Testing #
#######################
.PHONY: integration integ-modules-% cleanup-integ-buckets
integration: integ-modules-service
integ-modules-%:
@# integration command that uses the pattern to define the root path that
@# the module testing will start from. Strips off the "integ-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. test-modules-service_dynamodb
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst integ-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go test -timeout=10m -tags "integration" -v ${RUN_INTEG} -count 1 ./..."
cleanup-integ-buckets:
@echo "Cleaning up SDK integration resources"
go run -tags "integration" ./internal/awstesting/cmd/bucket_cleanup/main.go "aws-sdk-go-integration"
##############
# Benchmarks #
##############
.PHONY: bench bench-modules-%
bench: bench-modules-.
bench-modules-%:
@# benchmark command that uses the pattern to define the root path that
@# the module testing will start from. Strips off the "bench-modules-" and
@# replaces all "_" with "/".
@#
@# e.g. bench-modules-service_dynamodb
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst bench-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go test -timeout=10m -bench . --benchmem ${BUILD_TAGS} ${RUN_NONE} ./..."
#####################
# Release Process #
#####################
.PHONY: preview-release pre-release-validation release
ls-changes:
go run ${REPOTOOLS_CMD_CHANGELOG} ls
preview-release:
go run ${REPOTOOLS_CMD_CALCULATE_RELEASE} ${REPOTOOLS_CALCULATE_RELEASE_VERBOSE_FLAG} ${REPOTOOLS_CALCULATE_RELEASE_ADDITIONAL_ARGS}
pre-release-validation:
@if [[ -z "${RELEASE_MANIFEST_FILE}" ]]; then \
echo "RELEASE_MANIFEST_FILE is required to specify the file to write the release manifest" && false; \
fi
@if [[ -z "${RELEASE_CHGLOG_DESC_FILE}" ]]; then \
echo "RELEASE_CHGLOG_DESC_FILE is required to specify the file to write the release notes" && false; \
fi
release: pre-release-validation
go run ${REPOTOOLS_CMD_CALCULATE_RELEASE} -o ${RELEASE_MANIFEST_FILE} ${REPOTOOLS_CALCULATE_RELEASE_VERBOSE_FLAG} ${REPOTOOLS_CALCULATE_RELEASE_ADDITIONAL_ARGS}
go run ${REPOTOOLS_CMD_UPDATE_REQUIRES} -release ${RELEASE_MANIFEST_FILE}
go run ${REPOTOOLS_CMD_UPDATE_MODULE_METADATA} -release ${RELEASE_MANIFEST_FILE}
go run ${REPOTOOLS_CMD_GENERATE_CHANGELOG} -release ${RELEASE_MANIFEST_FILE} -o ${RELEASE_CHGLOG_DESC_FILE}
go run ${REPOTOOLS_CMD_CHANGELOG} rm -all
go run ${REPOTOOLS_CMD_TAG_RELEASE} -release ${RELEASE_MANIFEST_FILE}
##############
# Repo Tools #
##############
.PHONY: install-repotools
install-repotools:
go install ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION}
set-smithy-go-version:
@if [[ -z "${SMITHY_GO_VERSION}" ]]; then \
echo "SMITHY_GO_VERSION is required to update SDK's smithy-go module dependency version" && false; \
fi
go run ${REPOTOOLS_CMD_EDIT_MODULE_DEPENDENCY} -s "github.com/aws/smithy-go" -v "${SMITHY_GO_VERSION}"
##################
# Linting/Verify #
##################
.PHONY: verify lint vet vet-modules-% sdkv1check
verify: lint vet sdkv1check
lint:
@echo "go lint SDK and vendor packages"
@lint=`golint ./...`; \
dolint=`echo "$$lint" | grep -E -v \
-e ${LINT_IGNORE_S3MANAGER_INPUT} \
-e ${LINTIGNORESINGLEFIGHT} \
-e ${LINT_IGNORE_AWSRULESFN_ARN} \
-e ${LINT_IGNORE_AWSRULESFN_PARTITION}`; \
echo "$$dolint"; \
if [ "$$dolint" != "" ]; then exit 1; fi
vet: vet-modules-.
vet-modules-%:
cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst vet-modules-,,$@)) ${EACHMODULE_FLAGS} \
"go vet ${BUILD_TAGS} --all ./..."
sdkv1check:
@echo "Checking for usage of AWS SDK for Go v1"
@sdkv1usage=`go list -test -f '''{{ if not .Standard }}{{ range $$_, $$name := .Imports }} * {{ $$.ImportPath }} -> {{ $$name }}{{ print "\n" }}{{ end }}{{ range $$_, $$name := .TestImports }} *: {{ $$.ImportPath }} -> {{ $$name }}{{ print "\n" }}{{ end }}{{ end}}''' ./... | sort -u | grep '''/aws-sdk-go/'''`; \
echo "$$sdkv1usage"; \
if [ "$$sdkv1usage" != "" ]; then exit 1; fi
list-deps: list-deps-.
list-deps-%:
@# command that uses the pattern to define the root path that the
@# module testing will start from. Strips off the "list-deps-" and
@# replaces all "_" with "/".
@#
@# Trim output to only include stdout for list of dependencies only.
@# make list-deps 2>&-
@#
@# e.g. list-deps-internal_protocoltest
@cd ./internal/repotools/cmd/eachmodule \
&& go run . -p $(subst _,/,$(subst list-deps-,,$@)) ${EACHMODULE_FLAGS} \
"go list -m all | grep -v 'github.com/aws/aws-sdk-go-v2'" | sort -u
###################
# Sandbox Testing #
###################
.PHONY: sandbox-tests sandbox-build-% sandbox-run-% sandbox-test-% update-aws-golang-tip
sandbox-tests: sandbox-test-go1.15 sandbox-test-go1.16 sandbox-test-go1.17 sandbox-test-go1.18 sandbox-test-go1.19 sandbox-test-go1.20 sandbox-test-gotip
sandbox-build-%:
@# sandbox-build-go1.17
@# sandbox-build-gotip
@if [ $@ == sandbox-build-gotip ]; then\
docker build \
-f ./internal/awstesting/sandbox/Dockerfile.test.gotip \
-t "aws-sdk-go-$(subst sandbox-build-,,$@)" . ;\
else\
docker build \
--build-arg GO_VERSION=$(subst sandbox-build-go,,$@) \
-f ./internal/awstesting/sandbox/Dockerfile.test.goversion \
-t "aws-sdk-go-$(subst sandbox-build-,,$@)" . ;\
fi
sandbox-run-%: sandbox-build-%
@# sandbox-run-go1.17
@# sandbox-run-gotip
docker run -i -t "aws-sdk-go-$(subst sandbox-run-,,$@)" bash
sandbox-test-%: sandbox-build-%
@# sandbox-test-go1.17
@# sandbox-test-gotip
docker run -t "aws-sdk-go-$(subst sandbox-test-,,$@)"
update-aws-golang-tip:
docker build --no-cache=true -f ./internal/awstesting/sandbox/Dockerfile.golang-tip -t "aws-golang:tip" .

View file

@ -1,165 +0,0 @@
# AWS SDK for Go v2
[![Go Build status](https://github.com/aws/aws-sdk-go-v2/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/aws/aws-sdk-go-v2/actions/workflows/go.yml)[![Codegen Build status](https://github.com/aws/aws-sdk-go-v2/actions/workflows/codegen.yml/badge.svg?branch=main)](https://github.com/aws/aws-sdk-go-v2/actions/workflows/codegen.yml) [![SDK Documentation](https://img.shields.io/badge/SDK-Documentation-blue)](https://aws.github.io/aws-sdk-go-v2/docs/) [![Migration Guide](https://img.shields.io/badge/Migration-Guide-blue)](https://aws.github.io/aws-sdk-go-v2/docs/migrating/) [![API Reference](https://img.shields.io/badge/api-reference-blue.svg)](https://pkg.go.dev/mod/github.com/aws/aws-sdk-go-v2) [![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go-v2/blob/main/LICENSE.txt)
`aws-sdk-go-v2` is the v2 AWS SDK for the Go programming language.
The v2 SDK requires a minimum version of `Go 1.19`.
Check out the [release notes](https://github.com/aws/aws-sdk-go-v2/blob/main/CHANGELOG.md) for information about the latest bug
fixes, updates, and features added to the SDK.
Jump To:
* [Getting Started](#getting-started)
* [Getting Help](#getting-help)
* [Contributing](#feedback-and-contributing)
* [More Resources](#resources)
## Maintenance and support for SDK major versions
For information about maintenance and support for SDK major versions and their underlying dependencies, see the
following in the AWS SDKs and Tools Shared Configuration and Credentials Reference Guide:
* [AWS SDKs and Tools Maintenance Policy](https://docs.aws.amazon.com/credref/latest/refdocs/maint-policy.html)
* [AWS SDKs and Tools Version Support Matrix](https://docs.aws.amazon.com/credref/latest/refdocs/version-support-matrix.html)
### Go version support policy
The v2 SDK follows the upstream [release policy](https://go.dev/doc/devel/release#policy)
with an additional six months of support for the most recently deprecated
language version.
**AWS reserves the right to drop support for unsupported Go versions earlier to
address critical security issues.**
## Getting started
To get started working with the SDK setup your project for Go modules, and retrieve the SDK dependencies with `go get`.
This example shows how you can use the v2 SDK to make an API request using the SDK's [Amazon DynamoDB] client.
###### Initialize Project
```sh
$ mkdir ~/helloaws
$ cd ~/helloaws
$ go mod init helloaws
```
###### Add SDK Dependencies
```sh
$ go get github.com/aws/aws-sdk-go-v2/aws
$ go get github.com/aws/aws-sdk-go-v2/config
$ go get github.com/aws/aws-sdk-go-v2/service/dynamodb
```
###### Write Code
In your preferred editor add the following content to `main.go`
```go
package main
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)
func main() {
// Using the SDK's default configuration, loading additional config
// and credentials values from the environment variables, shared
// credentials, and shared configuration files
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"))
if err != nil {
log.Fatalf("unable to load SDK config, %v", err)
}
// Using the Config value, create the DynamoDB client
svc := dynamodb.NewFromConfig(cfg)
// Build the request with its input parameters
resp, err := svc.ListTables(context.TODO(), &dynamodb.ListTablesInput{
Limit: aws.Int32(5),
})
if err != nil {
log.Fatalf("failed to list tables, %v", err)
}
fmt.Println("Tables:")
for _, tableName := range resp.TableNames {
fmt.Println(tableName)
}
}
```
###### Compile and Execute
```sh
$ go run .
Tables:
tableOne
tableTwo
```
## Getting Help
Please use these community resources for getting help. We use the GitHub issues
for tracking bugs and feature requests.
* Ask us a [question](https://github.com/aws/aws-sdk-go-v2/discussions/new?category=q-a) or open a [discussion](https://github.com/aws/aws-sdk-go-v2/discussions/new?category=general).
* If you think you may have found a bug, please open an [issue](https://github.com/aws/aws-sdk-go-v2/issues/new/choose).
* Open a support ticket with [AWS Support](http://docs.aws.amazon.com/awssupport/latest/user/getting-started.html).
This SDK implements AWS service APIs. For general issues regarding the AWS services and their limitations, you may also take a look at the [Amazon Web Services Discussion Forums](https://forums.aws.amazon.com/).
### Opening Issues
If you encounter a bug with the AWS SDK for Go we would like to hear about it.
Search the [existing issues][Issues] and see
if others are also experiencing the same issue before opening a new issue. Please
include the version of AWS SDK for Go, Go language, and OS youre using. Please
also include reproduction case when appropriate.
The GitHub issues are intended for bug reports and feature requests. For help
and questions with using AWS SDK for Go please make use of the resources listed
in the [Getting Help](#getting-help) section.
Keeping the list of open issues lean will help us respond in a timely manner.
## Feedback and contributing
The v2 SDK will use GitHub [Issues] to track feature requests and issues with the SDK. In addition, we'll use GitHub [Projects] to track large tasks spanning multiple pull requests, such as refactoring the SDK's internal request lifecycle. You can provide feedback to us in several ways.
**GitHub issues**. To provide feedback or report bugs, file GitHub [Issues] on the SDK. This is the preferred mechanism to give feedback so that other users can engage in the conversation, +1 issues, etc. Issues you open will be evaluated, and included in our roadmap for the GA launch.
**Contributing**. You can open pull requests for fixes or additions to the AWS SDK for Go 2.0. All pull requests must be submitted under the Apache 2.0 license and will be reviewed by an SDK team member before being merged in. Accompanying unit tests, where possible, are appreciated.
## Resources
[SDK Developer Guide](https://aws.github.io/aws-sdk-go-v2/docs/) - Use this document to learn how to get started and
use the AWS SDK for Go V2.
[SDK Migration Guide](https://aws.github.io/aws-sdk-go-v2/docs/migrating/) - Use this document to learn how to migrate to V2 from the AWS SDK for Go.
[SDK API Reference Documentation](https://pkg.go.dev/mod/github.com/aws/aws-sdk-go-v2) - Use this
document to look up all API operation input and output parameters for AWS
services supported by the SDK. The API reference also includes documentation of
the SDK, and examples how to using the SDK, service client API operations, and
API operation require parameters.
[Service Documentation](https://aws.amazon.com/documentation/) - Use this
documentation to learn how to interface with AWS services. These guides are
great for getting started with a service, or when looking for more
information about a service. While this document is not required for coding,
services may supply helpful samples to look out for.
[Forum](https://forums.aws.amazon.com/forum.jspa?forumID=293) - Ask questions, get help, and give feedback
[Issues] - Report issues, submit pull requests, and get involved
(see [Apache 2.0 License][license])
[Dep]: https://github.com/golang/dep
[Issues]: https://github.com/aws/aws-sdk-go-v2/issues
[Projects]: https://github.com/aws/aws-sdk-go-v2/projects
[CHANGELOG]: https://github.com/aws/aws-sdk-go-v2/blob/main/CHANGELOG.md
[Amazon DynamoDB]: https://aws.amazon.com/dynamodb/
[design]: https://github.com/aws/aws-sdk-go-v2/blob/main/DESIGN.md
[license]: http://aws.amazon.com/apache2.0/

View file

@ -1,12 +0,0 @@
version: 0.2
phases:
build:
commands:
- echo Build started on `date`
- export GOPATH=/go
- export SDK_CODEBUILD_ROOT=`pwd`
- make ci-test-no-generate
post_build:
commands:
- echo Build completed on `date`

View file

@ -1,58 +0,0 @@
#!/bin/bash
# looks for (and modreplaces if existing) a smithy-go branch matching the
# current branch name
#
# the loop will unfurl -*s off of the branch, e.g. sdk branch
# 'feat-foo-bar-baz' will match any of the following (in order):
# - feat-foo-bar-baz
# - feat-foo-bar
# - feat-foo
if [ -z "$SMITHY_GO_REPOSITORY" ]; then
SMITHY_GO_REPOSITORY=aws/smithy-go
fi
if [ -z "$RUNNER_TMPDIR" ]; then
echo env RUNNER_TMPDIR is required
exit 1
fi
branch=$(git branch --show-current)
if [ "$branch" == main ]; then
echo aws-sdk-go-v2 is on branch main, stop
exit 0
fi
# For PR workflows, only the triggering ref is checked out, which in isolation
# is not recognized as a branch by git. Use the specific workflow env instead.
if [ -z "$branch" ]; then
branch=$GITHUB_HEAD_REF
fi
if [ -n "$GIT_PAT" ]; then
repository=https://$GIT_PAT@github.com/$SMITHY_GO_REPOSITORY
else
repository=https://github.com/$SMITHY_GO_REPOSITORY
fi
echo on branch \"$branch\"
while [ -n "$branch" ] && [[ "$branch" == *-* ]]; do
echo looking for "$branch"...
git ls-remote --exit-code --heads "$repository" refs/heads/"$branch"
if [ "$?" == 0 ]; then
echo found "$branch"
matched_branch=$branch
break
fi
branch=${branch%-*}
done
if [ -z "$matched_branch" ]; then
echo found no matching smithy-go branch, stop
exit 0
fi
git clone -b "$matched_branch" "$repository" "$RUNNER_TMPDIR"/smithy-go
SMITHY_GO_SRC=$RUNNER_TMPDIR/smithy-go make gen-mod-replace-smithy-.

View file

@ -1,3 +1,13 @@
# v1.25.0 (2023-11-14)
* **Feature**: Add support for dynamic auth token from file and EKS container host in absolute/relative URIs in the HTTP credential provider.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.0 (2023-11-13)
* **Feature**: Replace the legacy config parser with a modern, less-strict implementation. Parsing failures within a section will now simply ignore the invalid line rather than silently drop the entire section.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.23.0 (2023-11-09.2)
* **Feature**: BREAKFIX: In order to support subproperty parsing, invalid property definitions must not be ignored

View file

@ -3,4 +3,4 @@
package config
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.23.0"
const goModuleVersion = "1.25.0"

View file

@ -3,7 +3,10 @@ package config
import (
"context"
"fmt"
"io/ioutil"
"net"
"net/url"
"os"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
@ -24,8 +27,30 @@ const (
credSourceEc2Metadata = "Ec2InstanceMetadata"
credSourceEnvironment = "Environment"
credSourceECSContainer = "EcsContainer"
httpProviderAuthFileEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE"
)
// direct representation of the IPv4 address for the ECS container
// "169.254.170.2"
var ecsContainerIPv4 net.IP = []byte{
169, 254, 170, 2,
}
// direct representation of the IPv4 address for the EKS container
// "169.254.170.23"
var eksContainerIPv4 net.IP = []byte{
169, 254, 170, 23,
}
// direct representation of the IPv6 address for the EKS container
// "fd00:ec2::23"
var eksContainerIPv6 net.IP = []byte{
0xFD, 0, 0xE, 0xC2,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0x23,
}
var (
ecsContainerEndpoint = "http://169.254.170.2" // not constant to allow for swapping during unit-testing
)
@ -222,6 +247,36 @@ func processCredentials(ctx context.Context, cfg *aws.Config, sharedConfig *Shar
return nil
}
// isAllowedHost allows host to be loopback or known ECS/EKS container IPs
//
// host can either be an IP address OR an unresolved hostname - resolution will
// be automatically performed in the latter case
func isAllowedHost(host string) (bool, error) {
if ip := net.ParseIP(host); ip != nil {
return isIPAllowed(ip), nil
}
addrs, err := lookupHostFn(host)
if err != nil {
return false, err
}
for _, addr := range addrs {
if ip := net.ParseIP(addr); ip == nil || !isIPAllowed(ip) {
return false, nil
}
}
return true, nil
}
func isIPAllowed(ip net.IP) bool {
return ip.IsLoopback() ||
ip.Equal(ecsContainerIPv4) ||
ip.Equal(eksContainerIPv4) ||
ip.Equal(eksContainerIPv6)
}
func resolveLocalHTTPCredProvider(ctx context.Context, cfg *aws.Config, endpointURL, authToken string, configs configs) error {
var resolveErr error
@ -232,10 +287,12 @@ func resolveLocalHTTPCredProvider(ctx context.Context, cfg *aws.Config, endpoint
host := parsed.Hostname()
if len(host) == 0 {
resolveErr = fmt.Errorf("unable to parse host from local HTTP cred provider URL")
} else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil {
resolveErr = fmt.Errorf("failed to resolve host %q, %v", host, loopbackErr)
} else if !isLoopback {
resolveErr = fmt.Errorf("invalid endpoint host, %q, only loopback hosts are allowed", host)
} else if parsed.Scheme == "http" {
if isAllowedHost, allowHostErr := isAllowedHost(host); allowHostErr != nil {
resolveErr = fmt.Errorf("failed to resolve host %q, %v", host, allowHostErr)
} else if !isAllowedHost {
resolveErr = fmt.Errorf("invalid endpoint host, %q, only loopback/ecs/eks hosts are allowed", host)
}
}
}
@ -252,6 +309,16 @@ func resolveHTTPCredProvider(ctx context.Context, cfg *aws.Config, url, authToke
if len(authToken) != 0 {
options.AuthorizationToken = authToken
}
if authFilePath := os.Getenv(httpProviderAuthFileEnvVar); authFilePath != "" {
options.AuthorizationTokenProvider = endpointcreds.TokenProviderFunc(func() (string, error) {
var contents []byte
var err error
if contents, err = ioutil.ReadFile(authFilePath); err != nil {
return "", fmt.Errorf("failed to read authorization token from %v: %v", authFilePath, err)
}
return string(contents), nil
})
}
options.APIOptions = cfg.APIOptions
if cfg.Retryer != nil {
options.Retryer = cfg.Retryer()

View file

@ -1,3 +1,7 @@
# v1.16.0 (2023-11-14)
* **Feature**: Add support for dynamic auth token from file and EKS container host in absolute/relative URIs in the HTTP credential provider.
# v1.15.2 (2023-11-09)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -36,6 +36,7 @@ import (
"context"
"fmt"
"net/http"
"strings"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client"
@ -81,7 +82,37 @@ type Options struct {
// Optional authorization token value if set will be used as the value of
// the Authorization header of the endpoint credential request.
//
// When constructed from environment, the provider will use the value of
// AWS_CONTAINER_AUTHORIZATION_TOKEN environment variable as the token
//
// Will be overridden if AuthorizationTokenProvider is configured
AuthorizationToken string
// Optional auth provider func to dynamically load the auth token from a file
// everytime a credential is retrieved
//
// When constructed from environment, the provider will read and use the content
// of the file pointed to by AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE environment variable
// as the auth token everytime credentials are retrieved
//
// Will override AuthorizationToken if configured
AuthorizationTokenProvider AuthTokenProvider
}
// AuthTokenProvider defines an interface to dynamically load a value to be passed
// for the Authorization header of a credentials request.
type AuthTokenProvider interface {
GetToken() (string, error)
}
// TokenProviderFunc is a func type implementing AuthTokenProvider interface
// and enables customizing token provider behavior
type TokenProviderFunc func() (string, error)
// GetToken func retrieves auth token according to TokenProviderFunc implementation
func (p TokenProviderFunc) GetToken() (string, error) {
return p()
}
// New returns a credentials Provider for retrieving AWS credentials
@ -132,5 +163,30 @@ func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) {
}
func (p *Provider) getCredentials(ctx context.Context) (*client.GetCredentialsOutput, error) {
return p.client.GetCredentials(ctx, &client.GetCredentialsInput{AuthorizationToken: p.options.AuthorizationToken})
authToken, err := p.resolveAuthToken()
if err != nil {
return nil, fmt.Errorf("resolve auth token: %v", err)
}
return p.client.GetCredentials(ctx, &client.GetCredentialsInput{
AuthorizationToken: authToken,
})
}
func (p *Provider) resolveAuthToken() (string, error) {
authToken := p.options.AuthorizationToken
var err error
if p.options.AuthorizationTokenProvider != nil {
authToken, err = p.options.AuthorizationTokenProvider.GetToken()
if err != nil {
return "", err
}
}
if strings.ContainsAny(authToken, "\r\n") {
return "", fmt.Errorf("authorization token contains invalid newline sequence")
}
return authToken, nil
}

View file

@ -3,4 +3,4 @@
package credentials
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.15.2"
const goModuleVersion = "1.16.0"

View file

@ -1,58 +0,0 @@
// Package sdk is the official AWS SDK v2 for the Go programming language.
//
// aws-sdk-go-v2 is the the v2 of the AWS SDK for the Go programming language.
//
// # Getting started
//
// The best way to get started working with the SDK is to use `go get` to add the
// SDK and desired service clients to your Go dependencies explicitly.
//
// go get github.com/aws/aws-sdk-go-v2
// go get github.com/aws/aws-sdk-go-v2/config
// go get github.com/aws/aws-sdk-go-v2/service/dynamodb
//
// # Hello AWS
//
// This example shows how you can use the v2 SDK to make an API request using the
// SDK's Amazon DynamoDB client.
//
// package main
//
// import (
// "context"
// "fmt"
// "log"
//
// "github.com/aws/aws-sdk-go-v2/aws"
// "github.com/aws/aws-sdk-go-v2/config"
// "github.com/aws/aws-sdk-go-v2/service/dynamodb"
// )
//
// func main() {
// // Using the SDK's default configuration, loading additional config
// // and credentials values from the environment variables, shared
// // credentials, and shared configuration files
// cfg, err := config.LoadDefaultConfig(context.TODO(),
// config.WithRegion("us-west-2"),
// )
// if err != nil {
// log.Fatalf("unable to load SDK config, %v", err)
// }
//
// // Using the Config value, create the DynamoDB client
// svc := dynamodb.NewFromConfig(cfg)
//
// // Build the request with its input parameters
// resp, err := svc.ListTables(context.TODO(), &dynamodb.ListTablesInput{
// Limit: aws.Int32(5),
// })
// if err != nil {
// log.Fatalf("failed to list tables, %v", err)
// }
//
// fmt.Println("Tables:")
// for _, tableName := range resp.TableNames {
// fmt.Println(tableName)
// }
// }
package sdk

View file

@ -1,3 +1,11 @@
# v1.13.7 (2023-11-14)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.13.6 (2023-11-13)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.13.5 (2023-11-09.2)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package manager
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.13.5"
const goModuleVersion = "1.13.7"

View file

@ -1,3 +1,7 @@
# v1.7.0 (2023-11-13)
* **Feature**: Replace the legacy config parser with a modern, less-strict implementation. Parsing failures within a section will now simply ignore the invalid line rather than silently drop the entire section.
# v1.6.0 (2023-11-09.2)
* **Feature**: BREAKFIX: In order to support subproperty parsing, invalid property definitions must not be ignored

View file

@ -1,120 +0,0 @@
package ini
// ASTKind represents different states in the parse table
// and the type of AST that is being constructed
type ASTKind int
// ASTKind* is used in the parse table to transition between
// the different states
const (
ASTKindNone = ASTKind(iota)
ASTKindStart
ASTKindExpr
ASTKindEqualExpr
ASTKindStatement
ASTKindSkipStatement
ASTKindExprStatement
ASTKindSectionStatement
ASTKindNestedSectionStatement
ASTKindCompletedNestedSectionStatement
ASTKindCommentStatement
ASTKindCompletedSectionStatement
)
func (k ASTKind) String() string {
switch k {
case ASTKindNone:
return "none"
case ASTKindStart:
return "start"
case ASTKindExpr:
return "expr"
case ASTKindStatement:
return "stmt"
case ASTKindSectionStatement:
return "section_stmt"
case ASTKindExprStatement:
return "expr_stmt"
case ASTKindCommentStatement:
return "comment"
case ASTKindNestedSectionStatement:
return "nested_section_stmt"
case ASTKindCompletedSectionStatement:
return "completed_stmt"
case ASTKindSkipStatement:
return "skip"
default:
return ""
}
}
// AST interface allows us to determine what kind of node we
// are on and casting may not need to be necessary.
//
// The root is always the first node in Children
type AST struct {
Kind ASTKind
Root Token
RootToken bool
Children []AST
}
func newAST(kind ASTKind, root AST, children ...AST) AST {
return AST{
Kind: kind,
Children: append([]AST{root}, children...),
}
}
func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST {
return AST{
Kind: kind,
Root: root,
RootToken: true,
Children: children,
}
}
// AppendChild will append to the list of children an AST has.
func (a *AST) AppendChild(child AST) {
a.Children = append(a.Children, child)
}
// GetRoot will return the root AST which can be the first entry
// in the children list or a token.
func (a *AST) GetRoot() AST {
if a.RootToken {
return *a
}
if len(a.Children) == 0 {
return AST{}
}
return a.Children[0]
}
// GetChildren will return the current AST's list of children
func (a *AST) GetChildren() []AST {
if len(a.Children) == 0 {
return []AST{}
}
if a.RootToken {
return a.Children
}
return a.Children[1:]
}
// SetChildren will set and override all children of the AST.
func (a *AST) SetChildren(children []AST) {
if a.RootToken {
a.Children = children
} else {
a.Children = append(a.Children[:1], children...)
}
}
// Start is used to indicate the starting state of the parse table.
var Start = newAST(ASTKindStart, AST{})

View file

@ -1,11 +0,0 @@
package ini
var commaRunes = []rune(",")
func isComma(b rune) bool {
return b == ','
}
func newCommaToken() Token {
return newToken(TokenComma, commaRunes, NoneType)
}

View file

@ -1,35 +0,0 @@
package ini
// isComment will return whether or not the next byte(s) is a
// comment.
func isComment(b []rune) bool {
if len(b) == 0 {
return false
}
switch b[0] {
case ';':
return true
case '#':
return true
}
return false
}
// newCommentToken will create a comment token and
// return how many bytes were read.
func newCommentToken(b []rune) (Token, int, error) {
i := 0
for ; i < len(b); i++ {
if b[i] == '\n' {
break
}
if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' {
break
}
}
return newToken(TokenComment, b[:i], NoneType), i, nil
}

View file

@ -1,6 +0,0 @@
package ini
import (
// internal/ini module was carved out of this module
_ "github.com/aws/aws-sdk-go-v2"
)

View file

@ -1,43 +0,0 @@
// Package ini is an LL(1) parser for configuration files.
//
// Example:
// sections, err := ini.OpenFile("/path/to/file")
// if err != nil {
// panic(err)
// }
//
// profile := "foo"
// section, ok := sections.GetSection(profile)
// if !ok {
// fmt.Printf("section %q could not be found", profile)
// }
//
// Below is the BNF that describes this parser
//
// Grammar:
// stmt -> section | stmt'
// stmt' -> epsilon | expr
// expr -> value (stmt)* | equal_expr (stmt)*
// equal_expr -> value ( ':' | '=' ) equal_expr'
// equal_expr' -> number | string | quoted_string
// quoted_string -> " quoted_string'
// quoted_string' -> string quoted_string_end
// quoted_string_end -> "
//
// section -> [ section'
// section' -> section_value section_close
// section_value -> number | string_subset | boolean | quoted_string_subset
// quoted_string_subset -> " quoted_string_subset'
// quoted_string_subset' -> string_subset quoted_string_end
// quoted_string_subset -> "
// section_close -> ]
//
// value -> number | string_subset | boolean
// string -> ? UTF-8 Code-Points except '\n' (U+000A) and '\r\n' (U+000D U+000A) ?
// string_subset -> ? Code-points excepted by <string> grammar except ':' (U+003A), '=' (U+003D), '[' (U+005B), and ']' (U+005D) ?
//
// SkipState will skip (NL WS)+
//
// comment -> # comment' | ; comment'
// comment' -> epsilon | value
package ini

View file

@ -1,4 +0,0 @@
package ini
// emptyToken is used to satisfy the Token interface
var emptyToken = newToken(TokenNone, []rune{}, NoneType)

View file

@ -1,24 +0,0 @@
package ini
// newExpression will return an expression AST.
// Expr represents an expression
//
// grammar:
// expr -> string | number
func newExpression(tok Token) AST {
return newASTWithRootToken(ASTKindExpr, tok)
}
func newEqualExpr(left AST, tok Token) AST {
return newASTWithRootToken(ASTKindEqualExpr, tok, left)
}
// EqualExprKey will return a LHS value in the equal expr
func EqualExprKey(ast AST) string {
children := ast.GetChildren()
if len(children) == 0 || ast.Kind != ASTKindEqualExpr {
return ""
}
return string(children[0].Root.Raw())
}

View file

@ -3,4 +3,4 @@
package ini
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.6.0"
const goModuleVersion = "1.7.0"

View file

@ -1,13 +1,26 @@
// Package ini implements parsing of the AWS shared config file.
//
// Example:
// sections, err := ini.OpenFile("/path/to/file")
// if err != nil {
// panic(err)
// }
//
// profile := "foo"
// section, ok := sections.GetSection(profile)
// if !ok {
// fmt.Printf("section %q could not be found", profile)
// }
package ini
import (
"fmt"
"io"
"os"
"strings"
)
// OpenFile takes a path to a given file, and will open and parse
// that file.
// OpenFile parses shared config from the given file path.
func OpenFile(path string) (sections Sections, err error) {
f, oerr := os.Open(path)
if oerr != nil {
@ -26,33 +39,18 @@ func OpenFile(path string) (sections Sections, err error) {
return Parse(f, path)
}
// Parse will parse the given file using the shared config
// visitor.
func Parse(f io.Reader, path string) (Sections, error) {
tree, err := ParseAST(f)
// Parse parses shared config from the given reader.
func Parse(r io.Reader, path string) (Sections, error) {
contents, err := io.ReadAll(r)
if err != nil {
return Sections{}, err
return Sections{}, fmt.Errorf("read all: %v", err)
}
v := NewDefaultVisitor(path)
if err = Walk(tree, v); err != nil {
return Sections{}, err
}
return v.Sections, nil
}
// ParseBytes will parse the given bytes and return the parsed sections.
func ParseBytes(b []byte) (Sections, error) {
tree, err := ParseASTBytes(b)
lines := strings.Split(string(contents), "\n")
tokens, err := tokenize(lines)
if err != nil {
return Sections{}, err
return Sections{}, fmt.Errorf("tokenize: %v", err)
}
v := NewDefaultVisitor("")
if err = Walk(tree, v); err != nil {
return Sections{}, err
}
return v.Sections, nil
return parse(tokens, path), nil
}

View file

@ -1,161 +0,0 @@
package ini
import (
"bytes"
"io"
"io/ioutil"
)
// TokenType represents the various different tokens types
type TokenType int
func (t TokenType) String() string {
switch t {
case TokenNone:
return "none"
case TokenLit:
return "literal"
case TokenSep:
return "sep"
case TokenOp:
return "op"
case TokenWS:
return "ws"
case TokenNL:
return "newline"
case TokenComment:
return "comment"
case TokenComma:
return "comma"
default:
return ""
}
}
// TokenType enums
const (
TokenNone = TokenType(iota)
TokenLit
TokenSep
TokenComma
TokenOp
TokenWS
TokenNL
TokenComment
)
type iniLexer struct{}
// Tokenize will return a list of tokens during lexical analysis of the
// io.Reader.
func (l *iniLexer) Tokenize(r io.Reader) ([]Token, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, &UnableToReadFile{Err: err}
}
return l.tokenize(b)
}
func (l *iniLexer) tokenize(b []byte) ([]Token, error) {
runes := bytes.Runes(b)
var err error
n := 0
tokenAmount := countTokens(runes)
tokens := make([]Token, tokenAmount)
count := 0
for len(runes) > 0 && count < tokenAmount {
switch {
case isSubProperty(runes):
tokens[count], n, err = newLitToken(runes)
case isWhitespace(runes[0]):
tokens[count], n, err = newWSToken(runes)
case isComma(runes[0]):
tokens[count], n = newCommaToken(), 1
case isComment(runes):
tokens[count], n, err = newCommentToken(runes)
case isNewline(runes):
tokens[count], n, err = newNewlineToken(runes)
case isSep(runes):
tokens[count], n, err = newSepToken(runes)
case isOp(runes):
tokens[count], n, err = newOpToken(runes)
default:
tokens[count], n, err = newLitToken(runes)
}
if err != nil {
return nil, err
}
count++
runes = runes[n:]
}
return tokens[:count], nil
}
func countTokens(runes []rune) int {
count, n := 0, 0
var err error
for len(runes) > 0 {
switch {
case isSubProperty(runes):
_, n, err = newLitToken(runes)
case isWhitespace(runes[0]):
_, n, err = newWSToken(runes)
case isComma(runes[0]):
_, n = newCommaToken(), 1
case isComment(runes):
_, n, err = newCommentToken(runes)
case isNewline(runes):
_, n, err = newNewlineToken(runes)
case isSep(runes):
_, n, err = newSepToken(runes)
case isOp(runes):
_, n, err = newOpToken(runes)
default:
_, n, err = newLitToken(runes)
}
if err != nil {
return 0
}
count++
runes = runes[n:]
}
return count + 1
}
// Token indicates a metadata about a given value.
type Token struct {
t TokenType
ValueType ValueType
base int
raw []rune
}
var emptyValue = Value{}
func newToken(t TokenType, raw []rune, v ValueType) Token {
return Token{
t: t,
raw: raw,
ValueType: v,
}
}
// Raw return the raw runes that were consumed
func (tok Token) Raw() []rune {
return tok.raw
}
// Type returns the token type
func (tok Token) Type() TokenType {
return tok.t
}

View file

@ -1,356 +0,0 @@
package ini
import (
"fmt"
"io"
)
// ParseState represents the current state of the parser.
type ParseState uint
// State enums for the parse table
const (
InvalidState ParseState = iota
// stmt -> value stmt'
StatementState
// stmt' -> MarkComplete | op stmt
StatementPrimeState
// value -> number | string | boolean | quoted_string
ValueState
// section -> [ section'
OpenScopeState
// section' -> value section_close
SectionState
// section_close -> ]
CloseScopeState
// SkipState will skip (NL WS)+
SkipState
// SkipTokenState will skip any token and push the previous
// state onto the stack.
SkipTokenState
// comment -> # comment' | ; comment'
// comment' -> MarkComplete | value
CommentState
// MarkComplete state will complete statements and move that
// to the completed AST list
MarkCompleteState
// TerminalState signifies that the tokens have been fully parsed
TerminalState
)
// parseTable is a state machine to dictate the grammar above.
var parseTable = map[ASTKind]map[TokenType]ParseState{
ASTKindStart: {
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: TerminalState,
},
ASTKindCommentStatement: {
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindExpr: {
TokenOp: StatementPrimeState,
TokenLit: ValueState,
TokenSep: OpenScopeState,
TokenWS: ValueState,
TokenNL: SkipState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindEqualExpr: {
TokenLit: ValueState,
TokenSep: ValueState,
TokenOp: ValueState,
TokenWS: SkipTokenState,
TokenNL: SkipState,
},
ASTKindStatement: {
TokenLit: SectionState,
TokenSep: CloseScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindExprStatement: {
TokenLit: ValueState,
TokenSep: ValueState,
TokenOp: ValueState,
TokenWS: ValueState,
TokenNL: MarkCompleteState,
TokenComment: CommentState,
TokenNone: TerminalState,
TokenComma: SkipState,
},
ASTKindSectionStatement: {
TokenLit: SectionState,
TokenOp: SectionState,
TokenSep: CloseScopeState,
TokenWS: SectionState,
TokenNL: SkipTokenState,
},
ASTKindCompletedSectionStatement: {
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindSkipStatement: {
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: TerminalState,
},
}
// ParseAST will parse input from an io.Reader using
// an LL(1) parser.
func ParseAST(r io.Reader) ([]AST, error) {
lexer := iniLexer{}
tokens, err := lexer.Tokenize(r)
if err != nil {
return []AST{}, err
}
return parse(tokens)
}
// ParseASTBytes will parse input from a byte slice using
// an LL(1) parser.
func ParseASTBytes(b []byte) ([]AST, error) {
lexer := iniLexer{}
tokens, err := lexer.tokenize(b)
if err != nil {
return []AST{}, err
}
return parse(tokens)
}
func parse(tokens []Token) ([]AST, error) {
start := Start
stack := newParseStack(3, len(tokens))
stack.Push(start)
s := newSkipper()
loop:
for stack.Len() > 0 {
k := stack.Pop()
var tok Token
if len(tokens) == 0 {
// this occurs when all the tokens have been processed
// but reduction of what's left on the stack needs to
// occur.
tok = emptyToken
} else {
tok = tokens[0]
}
step := parseTable[k.Kind][tok.Type()]
if s.ShouldSkip(tok) {
// being in a skip state with no tokens will break out of
// the parse loop since there is nothing left to process.
if len(tokens) == 0 {
break loop
}
// if should skip is true, we skip the tokens until should skip is set to false.
step = SkipTokenState
}
switch step {
case TerminalState:
// Finished parsing. Push what should be the last
// statement to the stack. If there is anything left
// on the stack, an error in parsing has occurred.
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}
break loop
case SkipTokenState:
// When skipping a token, the previous state was popped off the stack.
// To maintain the correct state, the previous state will be pushed
// onto the stack.
stack.Push(k)
case StatementState:
if k.Kind != ASTKindStart {
if tok.Type() == TokenLit && isSubProperty(tok.raw) {
return nil, NewParseError(
fmt.Sprintf(
"Invalid token, remove leading whitespace %s",
string(tok.raw)),
)
}
stack.MarkComplete(k)
}
expr := newExpression(tok)
stack.Push(expr)
case StatementPrimeState:
if tok.Type() != TokenOp {
stack.MarkComplete(k)
continue
}
if k.Kind != ASTKindExpr {
return nil, NewParseError(
fmt.Sprintf("invalid expression: expected Expr type, but found %T type", k),
)
}
k = trimSpaces(k)
expr := newEqualExpr(k, tok)
stack.Push(expr)
case ValueState:
// ValueState requires the previous state to either be an equal expression
// or an expression statement.
switch k.Kind {
case ASTKindEqualExpr:
// assigning a value to some key
k.AppendChild(newExpression(tok))
stack.Push(newExprStatement(k))
case ASTKindExpr:
k.Root.raw = append(k.Root.raw, tok.Raw()...)
stack.Push(k)
case ASTKindExprStatement:
root := k.GetRoot()
children := root.GetChildren()
if len(children) == 0 {
return nil, NewParseError(
fmt.Sprintf("invalid expression: AST contains no children %s", k.Kind),
)
}
rhs := children[len(children)-1]
if rhs.Root.ValueType != QuotedStringType {
rhs.Root.ValueType = StringType
rhs.Root.raw = append(rhs.Root.raw, tok.Raw()...)
}
children[len(children)-1] = rhs
root.SetChildren(children)
stack.Push(k)
}
case OpenScopeState:
if !runeCompare(tok.Raw(), openBrace) {
return nil, NewParseError("expected '['")
}
// If OpenScopeState is not at the start, we must mark the previous ast as complete
//
// for example: if previous ast was a skip statement;
// we should mark it as complete before we create a new statement
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}
stmt := newStatement()
stack.Push(stmt)
case CloseScopeState:
if !runeCompare(tok.Raw(), closeBrace) {
return nil, NewParseError("expected ']'")
}
k = trimSpaces(k)
stack.Push(newCompletedSectionStatement(k))
case SectionState:
var stmt AST
switch k.Kind {
case ASTKindStatement:
// If there are multiple literals inside of a scope declaration,
// then the current token's raw value will be appended to the Name.
//
// This handles cases like [ profile default ]
//
// k will represent a SectionStatement with the children representing
// the label of the section
stmt = newSectionStatement(tok)
case ASTKindSectionStatement:
k.Root.raw = append(k.Root.raw, tok.Raw()...)
stmt = k
default:
return nil, NewParseError(
fmt.Sprintf("invalid statement: expected statement: %v", k.Kind),
)
}
stack.Push(stmt)
case MarkCompleteState:
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}
if stack.Len() == 0 {
stack.Push(start)
}
case SkipState:
stack.Push(newSkipStatement(k))
s.Skip()
case CommentState:
if k.Kind == ASTKindStart {
stack.Push(k)
} else {
stack.MarkComplete(k)
}
stmt := newCommentStatement(tok)
stack.Push(stmt)
default:
return nil, NewParseError(
fmt.Sprintf("invalid state with ASTKind %v and TokenType %v",
k.Kind, tok.Type()))
}
if len(tokens) > 0 {
tokens = tokens[1:]
}
}
// this occurs when a statement has not been completed
if stack.top > 1 {
return nil, NewParseError(fmt.Sprintf("incomplete ini expression"))
}
// returns a sublist which exludes the start symbol
return stack.List(), nil
}
// trimSpaces will trim spaces on the left and right hand side of
// the literal.
func trimSpaces(k AST) AST {
// trim left hand side of spaces
for i := 0; i < len(k.Root.raw); i++ {
if !isWhitespace(k.Root.raw[i]) {
break
}
k.Root.raw = k.Root.raw[1:]
i--
}
// trim right hand side of spaces
for i := len(k.Root.raw) - 1; i >= 0; i-- {
if !isWhitespace(k.Root.raw[i]) {
break
}
k.Root.raw = k.Root.raw[:len(k.Root.raw)-1]
}
return k
}

View file

@ -1,274 +0,0 @@
package ini
import (
"fmt"
"strconv"
"strings"
"unicode"
)
var (
runesTrue = []rune("true")
runesFalse = []rune("false")
)
// isCaselessLitValue is a caseless value comparison, assumes want is already lower-cased for efficiency.
func isCaselessLitValue(want, have []rune) bool {
if len(have) < len(want) {
return false
}
for i := 0; i < len(want); i++ {
if want[i] != unicode.ToLower(have[i]) {
return false
}
}
return true
}
func isValid(b []rune) (bool, int, error) {
if len(b) == 0 {
// TODO: should probably return an error
return false, 0, nil
}
return isValidRune(b[0]), 1, nil
}
func isValidRune(r rune) bool {
return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n'
}
// ValueType is an enum that will signify what type
// the Value is
type ValueType int
func (v ValueType) String() string {
switch v {
case NoneType:
return "NONE"
case StringType:
return "STRING"
}
return ""
}
// ValueType enums
const (
NoneType = ValueType(iota)
StringType
QuotedStringType
)
// Value is a union container
type Value struct {
Type ValueType
raw []rune
str string
mp map[string]string
}
func newValue(t ValueType, base int, raw []rune) (Value, error) {
v := Value{
Type: t,
raw: raw,
}
switch t {
case StringType:
v.str = string(raw)
if isSubProperty(raw) {
v.mp = v.MapValue()
}
case QuotedStringType:
v.str = string(raw[1 : len(raw)-1])
}
return v, nil
}
// NewStringValue returns a Value type generated using a string input.
func NewStringValue(str string) (Value, error) {
return newValue(StringType, 10, []rune(str))
}
func (v Value) String() string {
switch v.Type {
case StringType:
return fmt.Sprintf("string: %s", string(v.raw))
case QuotedStringType:
return fmt.Sprintf("quoted string: %s", string(v.raw))
default:
return "union not set"
}
}
func newLitToken(b []rune) (Token, int, error) {
n := 0
var err error
token := Token{}
if b[0] == '"' {
n, err = getStringValue(b)
if err != nil {
return token, n, err
}
token = newToken(TokenLit, b[:n], QuotedStringType)
} else if isSubProperty(b) {
offset := 0
end, err := getSubProperty(b, offset)
if err != nil {
return token, n, err
}
token = newToken(TokenLit, b[offset:end], StringType)
n = end
} else {
n, err = getValue(b)
token = newToken(TokenLit, b[:n], StringType)
}
return token, n, err
}
// replace with slices.Contains when Go 1.21
// is min supported Go version in the SDK
func containsRune(runes []rune, val rune) bool {
for i := range runes {
if val == runes[i] {
return true
}
}
return false
}
func isSubProperty(runes []rune) bool {
// needs at least
// (1) newline (2) whitespace (3) literal
if len(runes) < 3 {
return false
}
// must have an equal expression
if !containsRune(runes, '=') && !containsRune(runes, ':') {
return false
}
// must start with a new line
if !isNewline(runes) {
return false
}
_, n, err := newNewlineToken(runes)
if err != nil {
return false
}
// whitespace must follow newline
return isWhitespace(runes[n])
}
// getSubProperty pulls all subproperties and terminates when
// it hits a newline that is not the start of another subproperty.
// offset allows for removal of leading newline and whitespace
// characters
func getSubProperty(runes []rune, offset int) (int, error) {
for idx, val := range runes[offset:] {
if val == '\n' && !isSubProperty(runes[offset+idx:]) {
return offset + idx, nil
}
}
return offset + len(runes), nil
}
// MapValue returns a map value for sub properties
func (v Value) MapValue() map[string]string {
newlineParts := strings.Split(string(v.raw), "\n")
mp := make(map[string]string)
for _, part := range newlineParts {
operandParts := strings.Split(part, "=")
if len(operandParts) < 2 {
continue
}
key := strings.TrimSpace(operandParts[0])
val := strings.TrimSpace(operandParts[1])
mp[key] = val
}
return mp
}
// IntValue returns an integer value
func (v Value) IntValue() (int64, bool) {
i, err := strconv.ParseInt(string(v.raw), 0, 64)
if err != nil {
return 0, false
}
return i, true
}
// FloatValue returns a float value
func (v Value) FloatValue() (float64, bool) {
f, err := strconv.ParseFloat(string(v.raw), 64)
if err != nil {
return 0, false
}
return f, true
}
// BoolValue returns a bool value
func (v Value) BoolValue() (bool, bool) {
// we don't use ParseBool as it recognizes more than what we've
// historically supported
if isCaselessLitValue(runesTrue, v.raw) {
return true, true
} else if isCaselessLitValue(runesFalse, v.raw) {
return false, true
}
return false, false
}
func isTrimmable(r rune) bool {
switch r {
case '\n', ' ':
return true
}
return false
}
// StringValue returns the string value
func (v Value) StringValue() string {
switch v.Type {
case StringType:
return strings.TrimFunc(string(v.raw), isTrimmable)
case QuotedStringType:
// preserve all characters in the quotes
return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1]))
default:
return strings.TrimFunc(string(v.raw), isTrimmable)
}
}
func contains(runes []rune, c rune) bool {
for i := 0; i < len(runes); i++ {
if runes[i] == c {
return true
}
}
return false
}
func runeCompare(v1 []rune, v2 []rune) bool {
if len(v1) != len(v2) {
return false
}
for i := 0; i < len(v1); i++ {
if v1[i] != v2[i] {
return false
}
}
return true
}

View file

@ -1,30 +0,0 @@
package ini
func isNewline(b []rune) bool {
if len(b) == 0 {
return false
}
if b[0] == '\n' {
return true
}
if len(b) < 2 {
return false
}
return b[0] == '\r' && b[1] == '\n'
}
func newNewlineToken(b []rune) (Token, int, error) {
i := 1
if b[0] == '\r' && isNewline(b[1:]) {
i++
}
if !isNewline([]rune(b[:i])) {
return emptyToken, 0, NewParseError("invalid new line token")
}
return newToken(TokenNL, b[:i], NoneType), i, nil
}

View file

@ -1,39 +0,0 @@
package ini
import (
"fmt"
)
var (
equalOp = []rune("=")
equalColonOp = []rune(":")
)
func isOp(b []rune) bool {
if len(b) == 0 {
return false
}
switch b[0] {
case '=':
return true
case ':':
return true
default:
return false
}
}
func newOpToken(b []rune) (Token, int, error) {
tok := Token{}
switch b[0] {
case '=':
tok = newToken(TokenOp, equalOp, NoneType)
case ':':
tok = newToken(TokenOp, equalColonOp, NoneType)
default:
return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0]))
}
return tok, 1, nil
}

View file

@ -0,0 +1,109 @@
package ini
import (
"fmt"
"strings"
)
func parse(tokens []lineToken, path string) Sections {
parser := &parser{
path: path,
sections: NewSections(),
}
parser.parse(tokens)
return parser.sections
}
type parser struct {
csection, ckey string // current state
path string // source file path
sections Sections // parse result
}
func (p *parser) parse(tokens []lineToken) {
for _, otok := range tokens {
switch tok := otok.(type) {
case *lineTokenProfile:
p.handleProfile(tok)
case *lineTokenProperty:
p.handleProperty(tok)
case *lineTokenSubProperty:
p.handleSubProperty(tok)
case *lineTokenContinuation:
p.handleContinuation(tok)
}
}
}
func (p *parser) handleProfile(tok *lineTokenProfile) {
name := tok.Name
if tok.Type != "" {
name = fmt.Sprintf("%s %s", tok.Type, tok.Name)
}
p.ckey = ""
p.csection = name
if _, ok := p.sections.container[name]; !ok {
p.sections.container[name] = NewSection(name)
}
}
func (p *parser) handleProperty(tok *lineTokenProperty) {
if p.csection == "" {
return // LEGACY: don't error on "global" properties
}
p.ckey = tok.Key
if _, ok := p.sections.container[p.csection].values[tok.Key]; ok {
section := p.sections.container[p.csection]
section.Logs = append(p.sections.container[p.csection].Logs,
fmt.Sprintf(
"For profile: %v, overriding %v value, with a %v value found in a duplicate profile defined later in the same file %v. \n",
p.csection, tok.Key, tok.Key, p.path,
),
)
p.sections.container[p.csection] = section
}
p.sections.container[p.csection].values[tok.Key] = Value{
str: tok.Value,
}
p.sections.container[p.csection].SourceFile[tok.Key] = p.path
}
func (p *parser) handleSubProperty(tok *lineTokenSubProperty) {
if p.csection == "" {
return // LEGACY: don't error on "global" properties
}
if p.ckey == "" || p.sections.container[p.csection].values[p.ckey].str != "" {
// This is an "orphaned" subproperty, either because it's at
// the beginning of a section or because the last property's
// value isn't empty. Either way we're lenient here and
// "promote" this to a normal property.
p.handleProperty(&lineTokenProperty{
Key: tok.Key,
Value: strings.TrimSpace(trimComment(tok.Value)),
})
return
}
if p.sections.container[p.csection].values[p.ckey].mp == nil {
p.sections.container[p.csection].values[p.ckey] = Value{
mp: map[string]string{},
}
}
p.sections.container[p.csection].values[p.ckey].mp[tok.Key] = tok.Value
}
func (p *parser) handleContinuation(tok *lineTokenContinuation) {
if p.ckey == "" {
return
}
value, _ := p.sections.container[p.csection].values[p.ckey]
if value.str != "" && value.mp == nil {
value.str = fmt.Sprintf("%s\n%s", value.str, tok.Value)
}
p.sections.container[p.csection].values[p.ckey] = value
}

View file

@ -1,19 +0,0 @@
package ini
// ParseError is an error which is returned during any part of
// the parsing process.
type ParseError struct {
msg string
}
// NewParseError will return a new ParseError where message
// is the description of the error.
func NewParseError(message string) *ParseError {
return &ParseError{
msg: message,
}
}
func (err *ParseError) Error() string {
return err.msg
}

View file

@ -1,60 +0,0 @@
package ini
import (
"bytes"
"fmt"
)
// ParseStack is a stack that contains a container, the stack portion,
// and the list which is the list of ASTs that have been successfully
// parsed.
type ParseStack struct {
top int
container []AST
list []AST
index int
}
func newParseStack(sizeContainer, sizeList int) ParseStack {
return ParseStack{
container: make([]AST, sizeContainer),
list: make([]AST, sizeList),
}
}
// Pop will return and truncate the last container element.
func (s *ParseStack) Pop() AST {
s.top--
return s.container[s.top]
}
// Push will add the new AST to the container
func (s *ParseStack) Push(ast AST) {
s.container[s.top] = ast
s.top++
}
// MarkComplete will append the AST to the list of completed statements
func (s *ParseStack) MarkComplete(ast AST) {
s.list[s.index] = ast
s.index++
}
// List will return the completed statements
func (s ParseStack) List() []AST {
return s.list[:s.index]
}
// Len will return the length of the container
func (s *ParseStack) Len() int {
return s.top
}
func (s ParseStack) String() string {
buf := bytes.Buffer{}
for i, node := range s.list {
buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node))
}
return buf.String()
}

View file

@ -0,0 +1,157 @@
package ini
import (
"sort"
)
// Sections is a map of Section structures that represent
// a configuration.
type Sections struct {
container map[string]Section
}
// NewSections returns empty ini Sections
func NewSections() Sections {
return Sections{
container: make(map[string]Section, 0),
}
}
// GetSection will return section p. If section p does not exist,
// false will be returned in the second parameter.
func (t Sections) GetSection(p string) (Section, bool) {
v, ok := t.container[p]
return v, ok
}
// HasSection denotes if Sections consist of a section with
// provided name.
func (t Sections) HasSection(p string) bool {
_, ok := t.container[p]
return ok
}
// SetSection sets a section value for provided section name.
func (t Sections) SetSection(p string, v Section) Sections {
t.container[p] = v
return t
}
// DeleteSection deletes a section entry/value for provided section name./
func (t Sections) DeleteSection(p string) {
delete(t.container, p)
}
// values represents a map of union values.
type values map[string]Value
// List will return a list of all sections that were successfully
// parsed.
func (t Sections) List() []string {
keys := make([]string, len(t.container))
i := 0
for k := range t.container {
keys[i] = k
i++
}
sort.Strings(keys)
return keys
}
// Section contains a name and values. This represent
// a sectioned entry in a configuration file.
type Section struct {
// Name is the Section profile name
Name string
// values are the values within parsed profile
values values
// Errors is the list of errors
Errors []error
// Logs is the list of logs
Logs []string
// SourceFile is the INI Source file from where this section
// was retrieved. They key is the property, value is the
// source file the property was retrieved from.
SourceFile map[string]string
}
// NewSection returns an initialize section for the name
func NewSection(name string) Section {
return Section{
Name: name,
values: values{},
SourceFile: map[string]string{},
}
}
// List will return a list of all
// services in values
func (t Section) List() []string {
keys := make([]string, len(t.values))
i := 0
for k := range t.values {
keys[i] = k
i++
}
sort.Strings(keys)
return keys
}
// UpdateSourceFile updates source file for a property to provided filepath.
func (t Section) UpdateSourceFile(property string, filepath string) {
t.SourceFile[property] = filepath
}
// UpdateValue updates value for a provided key with provided value
func (t Section) UpdateValue(k string, v Value) error {
t.values[k] = v
return nil
}
// Has will return whether or not an entry exists in a given section
func (t Section) Has(k string) bool {
_, ok := t.values[k]
return ok
}
// ValueType will returned what type the union is set to. If
// k was not found, the NoneType will be returned.
func (t Section) ValueType(k string) (ValueType, bool) {
v, ok := t.values[k]
return v.Type, ok
}
// Bool returns a bool value at k
func (t Section) Bool(k string) (bool, bool) {
return t.values[k].BoolValue()
}
// Int returns an integer value at k
func (t Section) Int(k string) (int64, bool) {
return t.values[k].IntValue()
}
// Map returns a map value at k
func (t Section) Map(k string) map[string]string {
return t.values[k].MapValue()
}
// Float64 returns a float value at k
func (t Section) Float64(k string) (float64, bool) {
return t.values[k].FloatValue()
}
// String returns the string value at k
func (t Section) String(k string) string {
_, ok := t.values[k]
if !ok {
return ""
}
return t.values[k].StringValue()
}

View file

@ -1,41 +0,0 @@
package ini
import (
"fmt"
)
var (
emptyRunes = []rune{}
)
func isSep(b []rune) bool {
if len(b) == 0 {
return false
}
switch b[0] {
case '[', ']':
return true
default:
return false
}
}
var (
openBrace = []rune("[")
closeBrace = []rune("]")
)
func newSepToken(b []rune) (Token, int, error) {
tok := Token{}
switch b[0] {
case '[':
tok = newToken(TokenSep, openBrace, NoneType)
case ']':
tok = newToken(TokenSep, closeBrace, NoneType)
default:
return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0]))
}
return tok, 1, nil
}

View file

@ -1,45 +0,0 @@
package ini
// skipper is used to skip certain blocks of an ini file.
// Currently skipper is used to skip nested blocks of ini
// files. See example below
//
// [ foo ]
// nested = ; this section will be skipped
// a=b
// c=d
// bar=baz ; this will be included
type skipper struct {
shouldSkip bool
TokenSet bool
prevTok Token
}
func newSkipper() skipper {
return skipper{
prevTok: emptyToken,
}
}
func (s *skipper) ShouldSkip(tok Token) bool {
// should skip state will be modified only if previous token was new line (NL);
// and the current token is not WhiteSpace (WS).
if s.shouldSkip &&
s.prevTok.Type() == TokenNL &&
tok.Type() != TokenWS {
s.Continue()
return false
}
s.prevTok = tok
return s.shouldSkip
}
func (s *skipper) Skip() {
s.shouldSkip = true
}
func (s *skipper) Continue() {
s.shouldSkip = false
s.prevTok = emptyToken
}

View file

@ -1,35 +0,0 @@
package ini
// Statement is an empty AST mostly used for transitioning states.
func newStatement() AST {
return newAST(ASTKindStatement, AST{})
}
// SectionStatement represents a section AST
func newSectionStatement(tok Token) AST {
return newASTWithRootToken(ASTKindSectionStatement, tok)
}
// ExprStatement represents a completed expression AST
func newExprStatement(ast AST) AST {
return newAST(ASTKindExprStatement, ast)
}
// CommentStatement represents a comment in the ini defintion.
//
// grammar:
// comment -> #comment' | ;comment'
// comment' -> epsilon | value
func newCommentStatement(tok Token) AST {
return newAST(ASTKindCommentStatement, newExpression(tok))
}
// CompletedSectionStatement represents a completed section
func newCompletedSectionStatement(ast AST) AST {
return newAST(ASTKindCompletedSectionStatement, ast)
}
// SkipStatement is used to skip whole statements
func newSkipStatement(ast AST) AST {
return newAST(ASTKindSkipStatement, ast)
}

View file

@ -0,0 +1,83 @@
package ini
import "strings"
func trimComment(v string) string {
rest, _, _ := strings.Cut(v, "#")
rest, _, _ = strings.Cut(rest, ";")
return rest
}
// assumes no surrounding comment
func splitProperty(s string) (string, string, bool) {
equalsi := strings.Index(s, "=")
coloni := strings.Index(s, ":") // LEGACY: also supported for property assignment
sep := "="
if equalsi == -1 || coloni != -1 && coloni < equalsi {
sep = ":"
}
k, v, ok := strings.Cut(s, sep)
if !ok {
return "", "", false
}
return strings.TrimSpace(k), strings.TrimSpace(v), true
}
// assumes no surrounding comment, whitespace, or profile brackets
func splitProfile(s string) (string, string) {
var first int
for i, r := range s {
if isLineSpace(r) {
if first == 0 {
first = i
}
} else {
if first != 0 {
return s[:first], s[i:]
}
}
}
if first == 0 {
return "", s // type component is effectively blank
}
return "", ""
}
func isLineSpace(r rune) bool {
return r == ' ' || r == '\t'
}
func unquote(s string) string {
if isSingleQuoted(s) || isDoubleQuoted(s) {
return s[1 : len(s)-1]
}
return s
}
// applies various legacy conversions to property values:
// - remote wrapping single/doublequotes
// - expand escaped quote and newline sequences
func legacyStrconv(s string) string {
s = unquote(s)
s = strings.ReplaceAll(s, `\"`, `"`)
s = strings.ReplaceAll(s, `\'`, `'`)
s = strings.ReplaceAll(s, `\n`, "\n")
return s
}
func isSingleQuoted(s string) bool {
return hasAffixes(s, "'", "'")
}
func isDoubleQuoted(s string) bool {
return hasAffixes(s, `"`, `"`)
}
func isBracketed(s string) bool {
return hasAffixes(s, "[", "]")
}
func hasAffixes(s, left, right string) bool {
return strings.HasPrefix(s, left) && strings.HasSuffix(s, right)
}

View file

@ -0,0 +1,32 @@
package ini
type lineToken interface {
isLineToken()
}
type lineTokenProfile struct {
Type string
Name string
}
func (*lineTokenProfile) isLineToken() {}
type lineTokenProperty struct {
Key string
Value string
}
func (*lineTokenProperty) isLineToken() {}
type lineTokenContinuation struct {
Value string
}
func (*lineTokenContinuation) isLineToken() {}
type lineTokenSubProperty struct {
Key string
Value string
}
func (*lineTokenSubProperty) isLineToken() {}

View file

@ -0,0 +1,91 @@
package ini
import (
"strings"
)
func tokenize(lines []string) ([]lineToken, error) {
tokens := make([]lineToken, 0, len(lines))
for _, line := range lines {
if len(strings.TrimSpace(line)) == 0 || isLineComment(line) {
continue
}
if tok := asProfile(line); tok != nil {
tokens = append(tokens, tok)
} else if tok := asProperty(line); tok != nil {
tokens = append(tokens, tok)
} else if tok := asSubProperty(line); tok != nil {
tokens = append(tokens, tok)
} else if tok := asContinuation(line); tok != nil {
tokens = append(tokens, tok)
} // unrecognized tokens are effectively ignored
}
return tokens, nil
}
func isLineComment(line string) bool {
trimmed := strings.TrimLeft(line, " \t")
return strings.HasPrefix(trimmed, "#") || strings.HasPrefix(trimmed, ";")
}
func asProfile(line string) *lineTokenProfile { // " [ type name ] ; comment"
trimmed := strings.TrimSpace(trimComment(line)) // "[ type name ]"
if !isBracketed(trimmed) {
return nil
}
trimmed = trimmed[1 : len(trimmed)-1] // " type name " (or just " name ")
trimmed = strings.TrimSpace(trimmed) // "type name" / "name"
typ, name := splitProfile(trimmed)
return &lineTokenProfile{
Type: typ,
Name: name,
}
}
func asProperty(line string) *lineTokenProperty {
if isLineSpace(rune(line[0])) {
return nil
}
trimmed := strings.TrimRight(trimComment(line), " \t")
k, v, ok := splitProperty(trimmed)
if !ok {
return nil
}
return &lineTokenProperty{
Key: strings.ToLower(k), // LEGACY: normalize key case
Value: legacyStrconv(v), // LEGACY: see func docs
}
}
func asSubProperty(line string) *lineTokenSubProperty {
if !isLineSpace(rune(line[0])) {
return nil
}
// comments on sub-properties are included in the value
trimmed := strings.TrimLeft(line, " \t")
k, v, ok := splitProperty(trimmed)
if !ok {
return nil
}
return &lineTokenSubProperty{ // same LEGACY constraints as in normal property
Key: strings.ToLower(k),
Value: legacyStrconv(v),
}
}
func asContinuation(line string) *lineTokenContinuation {
if !isLineSpace(rune(line[0])) {
return nil
}
// includes comments like sub-properties
trimmed := strings.TrimLeft(line, " \t")
return &lineTokenContinuation{
Value: trimmed,
}
}

View file

@ -0,0 +1,104 @@
package ini
import (
"fmt"
"strconv"
"strings"
)
// ValueType is an enum that will signify what type
// the Value is
type ValueType int
func (v ValueType) String() string {
switch v {
case NoneType:
return "NONE"
case StringType:
return "STRING"
}
return ""
}
// ValueType enums
const (
NoneType = ValueType(iota)
StringType
QuotedStringType
)
// Value is a union container
type Value struct {
Type ValueType
str string
mp map[string]string
}
// NewStringValue returns a Value type generated using a string input.
func NewStringValue(str string) (Value, error) {
return Value{str: str}, nil
}
func (v Value) String() string {
switch v.Type {
case StringType:
return fmt.Sprintf("string: %s", string(v.str))
case QuotedStringType:
return fmt.Sprintf("quoted string: %s", string(v.str))
default:
return "union not set"
}
}
// MapValue returns a map value for sub properties
func (v Value) MapValue() map[string]string {
newlineParts := strings.Split(string(v.str), "\n")
mp := make(map[string]string)
for _, part := range newlineParts {
operandParts := strings.Split(part, "=")
if len(operandParts) < 2 {
continue
}
key := strings.TrimSpace(operandParts[0])
val := strings.TrimSpace(operandParts[1])
mp[key] = val
}
return mp
}
// IntValue returns an integer value
func (v Value) IntValue() (int64, bool) {
i, err := strconv.ParseInt(string(v.str), 0, 64)
if err != nil {
return 0, false
}
return i, true
}
// FloatValue returns a float value
func (v Value) FloatValue() (float64, bool) {
f, err := strconv.ParseFloat(string(v.str), 64)
if err != nil {
return 0, false
}
return f, true
}
// BoolValue returns a bool value
func (v Value) BoolValue() (bool, bool) {
// we don't use ParseBool as it recognizes more than what we've
// historically supported
if strings.EqualFold(v.str, "true") {
return true, true
} else if strings.EqualFold(v.str, "false") {
return false, true
}
return false, false
}
// StringValue returns the string value
func (v Value) StringValue() string {
return v.str
}

View file

@ -1,123 +0,0 @@
package ini
import (
"fmt"
)
// getStringValue will return a quoted string and the amount
// of bytes read
//
// an error will be returned if the string is not properly formatted
func getStringValue(b []rune) (int, error) {
if b[0] != '"' {
return 0, NewParseError("strings must start with '\"'")
}
endQuote := false
i := 1
for ; i < len(b) && !endQuote; i++ {
if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
endQuote = true
break
} else if escaped {
/*c, err := getEscapedByte(b[i])
if err != nil {
return 0, err
}
b[i-1] = c
b = append(b[:i], b[i+1:]...)
i--*/
continue
}
}
if !endQuote {
return 0, NewParseError("missing '\"' in string value")
}
return i + 1, nil
}
func getValue(b []rune) (int, error) {
i := 0
for i < len(b) {
if isNewline(b[i:]) {
break
}
if isOp(b[i:]) {
break
}
valid, n, err := isValid(b[i:])
if err != nil {
return 0, err
}
if !valid {
break
}
i += n
}
return i, nil
}
// isEscaped will return whether or not the character is an escaped
// character.
func isEscaped(value []rune, b rune) bool {
if len(value) == 0 {
return false
}
switch b {
case '\'': // single quote
case '"': // quote
case 'n': // newline
case 't': // tab
case '\\': // backslash
default:
return false
}
return value[len(value)-1] == '\\'
}
func getEscapedByte(b rune) (rune, error) {
switch b {
case '\'': // single quote
return '\'', nil
case '"': // quote
return '"', nil
case 'n': // newline
return '\n', nil
case 't': // table
return '\t', nil
case '\\': // backslash
return '\\', nil
default:
return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
}
}
func removeEscapedCharacters(b []rune) []rune {
for i := 0; i < len(b); i++ {
if isEscaped(b[:i], b[i]) {
c, err := getEscapedByte(b[i])
if err != nil {
return b
}
b[i-1] = c
b = append(b[:i], b[i+1:]...)
i--
}
}
return b
}

View file

@ -1,288 +0,0 @@
package ini
import (
"fmt"
"sort"
"strings"
)
// Visitor is an interface used by walkers that will
// traverse an array of ASTs.
type Visitor interface {
VisitExpr(AST) error
VisitStatement(AST) error
}
// DefaultVisitor is used to visit statements and expressions
// and ensure that they are both of the correct format.
// In addition, upon visiting this will build sections and populate
// the Sections field which can be used to retrieve profile
// configuration.
type DefaultVisitor struct {
// scope is the profile which is being visited
scope string
// path is the file path which the visitor is visiting
path string
// Sections defines list of the profile section
Sections Sections
}
// NewDefaultVisitor returns a DefaultVisitor. It takes in a filepath
// which points to the file it is visiting.
func NewDefaultVisitor(filepath string) *DefaultVisitor {
return &DefaultVisitor{
Sections: Sections{
container: map[string]Section{},
},
path: filepath,
}
}
// VisitExpr visits expressions...
func (v *DefaultVisitor) VisitExpr(expr AST) error {
t := v.Sections.container[v.scope]
if t.values == nil {
t.values = values{}
}
if t.SourceFile == nil {
t.SourceFile = make(map[string]string, 0)
}
switch expr.Kind {
case ASTKindExprStatement:
opExpr := expr.GetRoot()
switch opExpr.Kind {
case ASTKindEqualExpr:
children := opExpr.GetChildren()
if len(children) <= 1 {
return NewParseError("unexpected token type")
}
rhs := children[1]
// The right-hand value side the equality expression is allowed to contain '[', ']', ':', '=' in the values.
// If the token is not either a literal or one of the token types that identifies those four additional
// tokens then error.
if !(rhs.Root.Type() == TokenLit || rhs.Root.Type() == TokenOp || rhs.Root.Type() == TokenSep) {
return NewParseError("unexpected token type")
}
key := EqualExprKey(opExpr)
val, err := newValue(rhs.Root.ValueType, rhs.Root.base, rhs.Root.Raw())
if err != nil {
return err
}
// lower case key to standardize
k := strings.ToLower(key)
// identify if the section already had this key, append log on section
if t.Has(k) {
t.Logs = append(t.Logs,
fmt.Sprintf("For profile: %v, overriding %v value, "+
"with a %v value found in a duplicate profile defined later in the same file %v. \n",
t.Name, k, k, v.path))
}
// assign the value
t.values[k] = val
// update the source file path for region
t.SourceFile[k] = v.path
default:
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
}
default:
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
}
v.Sections.container[v.scope] = t
return nil
}
// VisitStatement visits statements...
func (v *DefaultVisitor) VisitStatement(stmt AST) error {
switch stmt.Kind {
case ASTKindCompletedSectionStatement:
child := stmt.GetRoot()
if child.Kind != ASTKindSectionStatement {
return NewParseError(fmt.Sprintf("unsupported child statement: %T", child))
}
name := string(child.Root.Raw())
// trim start and end space
name = strings.TrimSpace(name)
// if has prefix "profile " + [ws+] + "profile-name",
// we standardize by removing the [ws+] between prefix and profile-name.
if strings.HasPrefix(name, "profile ") {
names := strings.SplitN(name, " ", 2)
name = names[0] + " " + strings.TrimLeft(names[1], " ")
}
// attach profile name on section
if !v.Sections.HasSection(name) {
v.Sections.container[name] = NewSection(name)
}
v.scope = name
default:
return NewParseError(fmt.Sprintf("unsupported statement: %s", stmt.Kind))
}
return nil
}
// Sections is a map of Section structures that represent
// a configuration.
type Sections struct {
container map[string]Section
}
// NewSections returns empty ini Sections
func NewSections() Sections {
return Sections{
container: make(map[string]Section, 0),
}
}
// GetSection will return section p. If section p does not exist,
// false will be returned in the second parameter.
func (t Sections) GetSection(p string) (Section, bool) {
v, ok := t.container[p]
return v, ok
}
// HasSection denotes if Sections consist of a section with
// provided name.
func (t Sections) HasSection(p string) bool {
_, ok := t.container[p]
return ok
}
// SetSection sets a section value for provided section name.
func (t Sections) SetSection(p string, v Section) Sections {
t.container[p] = v
return t
}
// DeleteSection deletes a section entry/value for provided section name./
func (t Sections) DeleteSection(p string) {
delete(t.container, p)
}
// values represents a map of union values.
type values map[string]Value
// List will return a list of all sections that were successfully
// parsed.
func (t Sections) List() []string {
keys := make([]string, len(t.container))
i := 0
for k := range t.container {
keys[i] = k
i++
}
sort.Strings(keys)
return keys
}
// Section contains a name and values. This represent
// a sectioned entry in a configuration file.
type Section struct {
// Name is the Section profile name
Name string
// values are the values within parsed profile
values values
// Errors is the list of errors
Errors []error
// Logs is the list of logs
Logs []string
// SourceFile is the INI Source file from where this section
// was retrieved. They key is the property, value is the
// source file the property was retrieved from.
SourceFile map[string]string
}
// NewSection returns an initialize section for the name
func NewSection(name string) Section {
return Section{
Name: name,
values: values{},
SourceFile: map[string]string{},
}
}
// List will return a list of all
// services in values
func (t Section) List() []string {
keys := make([]string, len(t.values))
i := 0
for k := range t.values {
keys[i] = k
i++
}
sort.Strings(keys)
return keys
}
// UpdateSourceFile updates source file for a property to provided filepath.
func (t Section) UpdateSourceFile(property string, filepath string) {
t.SourceFile[property] = filepath
}
// UpdateValue updates value for a provided key with provided value
func (t Section) UpdateValue(k string, v Value) error {
t.values[k] = v
return nil
}
// Has will return whether or not an entry exists in a given section
func (t Section) Has(k string) bool {
_, ok := t.values[k]
return ok
}
// ValueType will returned what type the union is set to. If
// k was not found, the NoneType will be returned.
func (t Section) ValueType(k string) (ValueType, bool) {
v, ok := t.values[k]
return v.Type, ok
}
// Bool returns a bool value at k
func (t Section) Bool(k string) (bool, bool) {
return t.values[k].BoolValue()
}
// Int returns an integer value at k
func (t Section) Int(k string) (int64, bool) {
return t.values[k].IntValue()
}
// Map returns a map value at k
func (t Section) Map(k string) map[string]string {
return t.values[k].MapValue()
}
// Float64 returns a float value at k
func (t Section) Float64(k string) (float64, bool) {
return t.values[k].FloatValue()
}
// String returns the string value at k
func (t Section) String(k string) string {
_, ok := t.values[k]
if !ok {
return ""
}
return t.values[k].StringValue()
}

View file

@ -1,25 +0,0 @@
package ini
// Walk will traverse the AST using the v, the Visitor.
func Walk(tree []AST, v Visitor) error {
for _, node := range tree {
switch node.Kind {
case ASTKindExpr,
ASTKindExprStatement:
if err := v.VisitExpr(node); err != nil {
return err
}
case ASTKindStatement,
ASTKindCompletedSectionStatement,
ASTKindNestedSectionStatement,
ASTKindCompletedNestedSectionStatement:
if err := v.VisitStatement(node); err != nil {
return err
}
}
}
return nil
}

View file

@ -1,24 +0,0 @@
package ini
import (
"unicode"
)
// isWhitespace will return whether or not the character is
// a whitespace character.
//
// Whitespace is defined as a space or tab.
func isWhitespace(c rune) bool {
return unicode.IsSpace(c) && c != '\n' && c != '\r'
}
func newWSToken(b []rune) (Token, int, error) {
i := 0
for ; i < len(b); i++ {
if !isWhitespace(b[i]) {
break
}
}
return newToken(TokenWS, b[:i], NoneType), i, nil
}

View file

@ -1,39 +0,0 @@
#!/usr/bin/env bash
PROJECT_DIR=""
SDK_SOURCE_DIR=$(cd `dirname $0` && pwd)
usage() {
echo "Usage: $0 [-s SDK_SOURCE_DIR] [-d PROJECT_DIR]" 1>&2
exit 1
}
while getopts "hs:d:" options; do
case "${options}" in
s)
SDK_SOURCE_DIR=${OPTARG}
if [ "$SDK_SOURCE_DIR" == "" ]; then
echo "path to SDK source directory is required" || exit
usage
fi
;;
d)
PROJECT_DIR=${OPTARG}
;;
h)
usage
;;
*)
usage
;;
esac
done
if [ "$PROJECT_DIR" != "" ]; then
cd "$PROJECT_DIR" || exit
fi
go mod graph | awk '{print $1}' | cut -d '@' -f 1 | sort | uniq | grep "github.com/aws/aws-sdk-go-v2" | while read x; do
repPath=${x/github.com\/aws\/aws-sdk-go-v2/${SDK_SOURCE_DIR}}
echo -replace $x=$repPath
done | xargs go mod edit

View file

@ -1,78 +0,0 @@
[dependencies]
"github.com/aws/aws-sdk-go" = "v1.44.28"
"github.com/aws/smithy-go" = "v1.16.0"
"github.com/google/go-cmp" = "v0.5.8"
"github.com/jmespath/go-jmespath" = "v0.4.0"
"golang.org/x/net" = "v0.1.0"
[modules]
[modules."."]
metadata_package = "aws"
[modules.codegen]
no_tag = true
[modules."example/service/dynamodb/createTable"]
no_tag = true
[modules."example/service/dynamodb/scanItems"]
no_tag = true
[modules."example/service/s3/listObjects"]
no_tag = true
[modules."example/service/s3/usingPrivateLink"]
no_tag = true
[modules."feature/ec2/imds/internal/configtesting"]
no_tag = true
[modules."internal/codegen"]
no_tag = true
[modules."internal/configsources/configtesting"]
no_tag = true
[modules."internal/protocoltest/awsrestjson"]
no_tag = true
[modules."internal/protocoltest/ec2query"]
no_tag = true
[modules."internal/protocoltest/jsonrpc"]
no_tag = true
[modules."internal/protocoltest/jsonrpc10"]
no_tag = true
[modules."internal/protocoltest/query"]
no_tag = true
[modules."internal/protocoltest/restxml"]
no_tag = true
[modules."internal/protocoltest/restxmlwithnamespace"]
no_tag = true
[modules."internal/repotools"]
no_tag = true
[modules."internal/repotools/changes"]
no_tag = true
[modules."service/internal/benchmark"]
no_tag = true
[modules."service/internal/integrationtest"]
no_tag = true
[modules."service/kinesis/internal/testing"]
no_tag = true
[modules."service/s3/internal/configtesting"]
no_tag = true
[modules."service/transcribestreaming/internal/testing"]
no_tag = true

View file

@ -31,6 +31,8 @@ package endpointcreds
import (
"encoding/json"
"fmt"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
@ -69,7 +71,37 @@ type Provider struct {
// Optional authorization token value if set will be used as the value of
// the Authorization header of the endpoint credential request.
//
// When constructed from environment, the provider will use the value of
// AWS_CONTAINER_AUTHORIZATION_TOKEN environment variable as the token
//
// Will be overridden if AuthorizationTokenProvider is configured
AuthorizationToken string
// Optional auth provider func to dynamically load the auth token from a file
// everytime a credential is retrieved
//
// When constructed from environment, the provider will read and use the content
// of the file pointed to by AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE environment variable
// as the auth token everytime credentials are retrieved
//
// Will override AuthorizationToken if configured
AuthorizationTokenProvider AuthTokenProvider
}
// AuthTokenProvider defines an interface to dynamically load a value to be passed
// for the Authorization header of a credentials request.
type AuthTokenProvider interface {
GetToken() (string, error)
}
// TokenProviderFunc is a func type implementing AuthTokenProvider interface
// and enables customizing token provider behavior
type TokenProviderFunc func() (string, error)
// GetToken func retrieves auth token according to TokenProviderFunc implementation
func (p TokenProviderFunc) GetToken() (string, error) {
return p()
}
// NewProviderClient returns a credentials Provider for retrieving AWS credentials
@ -164,7 +196,20 @@ func (p *Provider) getCredentials(ctx aws.Context) (*getCredentialsOutput, error
req := p.Client.NewRequest(op, nil, out)
req.SetContext(ctx)
req.HTTPRequest.Header.Set("Accept", "application/json")
if authToken := p.AuthorizationToken; len(authToken) != 0 {
authToken := p.AuthorizationToken
var err error
if p.AuthorizationTokenProvider != nil {
authToken, err = p.AuthorizationTokenProvider.GetToken()
if err != nil {
return nil, fmt.Errorf("get authorization token: %v", err)
}
}
if strings.ContainsAny(authToken, "\r\n") {
return nil, fmt.Errorf("authorization token contains invalid newline sequence")
}
if len(authToken) != 0 {
req.HTTPRequest.Header.Set("Authorization", authToken)
}

View file

@ -9,6 +9,7 @@ package defaults
import (
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
@ -115,9 +116,31 @@ func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Pro
const (
httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
httpProviderAuthFileEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE"
httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
)
// direct representation of the IPv4 address for the ECS container
// "169.254.170.2"
var ecsContainerIPv4 net.IP = []byte{
169, 254, 170, 2,
}
// direct representation of the IPv4 address for the EKS container
// "169.254.170.23"
var eksContainerIPv4 net.IP = []byte{
169, 254, 170, 23,
}
// direct representation of the IPv6 address for the EKS container
// "fd00:ec2::23"
var eksContainerIPv6 net.IP = []byte{
0xFD, 0, 0xE, 0xC2,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0x23,
}
// RemoteCredProvider returns a credentials provider for the default remote
// endpoints such as EC2 or ECS Roles.
func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
@ -135,19 +158,22 @@ func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.P
var lookupHostFn = net.LookupHost
func isLoopbackHost(host string) (bool, error) {
ip := net.ParseIP(host)
if ip != nil {
return ip.IsLoopback(), nil
// isAllowedHost allows host to be loopback or known ECS/EKS container IPs
//
// host can either be an IP address OR an unresolved hostname - resolution will
// be automatically performed in the latter case
func isAllowedHost(host string) (bool, error) {
if ip := net.ParseIP(host); ip != nil {
return isIPAllowed(ip), nil
}
// Host is not an ip, perform lookup
addrs, err := lookupHostFn(host)
if err != nil {
return false, err
}
for _, addr := range addrs {
if !net.ParseIP(addr).IsLoopback() {
if ip := net.ParseIP(addr); ip == nil || !isIPAllowed(ip) {
return false, nil
}
}
@ -155,6 +181,13 @@ func isLoopbackHost(host string) (bool, error) {
return true, nil
}
func isIPAllowed(ip net.IP) bool {
return ip.IsLoopback() ||
ip.Equal(ecsContainerIPv4) ||
ip.Equal(eksContainerIPv4) ||
ip.Equal(eksContainerIPv6)
}
func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
var errMsg string
@ -165,10 +198,12 @@ func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string)
host := aws.URLHostname(parsed)
if len(host) == 0 {
errMsg = "unable to parse host from local HTTP cred provider URL"
} else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil {
errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr)
} else if !isLoopback {
errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host)
} else if parsed.Scheme == "http" {
if isAllowedHost, allowHostErr := isAllowedHost(host); allowHostErr != nil {
errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, allowHostErr)
} else if !isAllowedHost {
errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback/ecs/eks hosts are allowed.", host)
}
}
}
@ -190,6 +225,15 @@ func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) crede
func(p *endpointcreds.Provider) {
p.ExpiryWindow = 5 * time.Minute
p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar)
if authFilePath := os.Getenv(httpProviderAuthFileEnvVar); authFilePath != "" {
p.AuthorizationTokenProvider = endpointcreds.TokenProviderFunc(func() (string, error) {
if contents, err := ioutil.ReadFile(authFilePath); err != nil {
return "", fmt.Errorf("failed to read authorization token from %v: %v", authFilePath, err)
} else {
return string(contents), nil
}
})
}
},
)
}

View file

@ -6214,15 +6214,27 @@ var awsPartition = partition{
endpointKey{
Region: "ap-northeast-2",
}: endpoint{},
endpointKey{
Region: "ap-northeast-3",
}: endpoint{},
endpointKey{
Region: "ap-south-1",
}: endpoint{},
endpointKey{
Region: "ap-south-2",
}: endpoint{},
endpointKey{
Region: "ap-southeast-1",
}: endpoint{},
endpointKey{
Region: "ap-southeast-2",
}: endpoint{},
endpointKey{
Region: "ap-southeast-3",
}: endpoint{},
endpointKey{
Region: "ap-southeast-4",
}: endpoint{},
endpointKey{
Region: "ca-central-1",
}: endpoint{},
@ -6244,6 +6256,9 @@ var awsPartition = partition{
endpointKey{
Region: "eu-south-1",
}: endpoint{},
endpointKey{
Region: "eu-south-2",
}: endpoint{},
endpointKey{
Region: "eu-west-1",
}: endpoint{},
@ -6298,6 +6313,12 @@ var awsPartition = partition{
},
Deprecated: boxedTrue,
},
endpointKey{
Region: "il-central-1",
}: endpoint{},
endpointKey{
Region: "me-central-1",
}: endpoint{},
endpointKey{
Region: "me-south-1",
}: endpoint{},
@ -6993,6 +7014,14 @@ var awsPartition = partition{
Region: "ap-south-1",
},
},
endpointKey{
Region: "ap-south-2",
}: endpoint{
Hostname: "compute-optimizer.ap-south-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-south-2",
},
},
endpointKey{
Region: "ap-southeast-1",
}: endpoint{
@ -7009,6 +7038,22 @@ var awsPartition = partition{
Region: "ap-southeast-2",
},
},
endpointKey{
Region: "ap-southeast-3",
}: endpoint{
Hostname: "compute-optimizer.ap-southeast-3.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-southeast-3",
},
},
endpointKey{
Region: "ap-southeast-4",
}: endpoint{
Hostname: "compute-optimizer.ap-southeast-4.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-southeast-4",
},
},
endpointKey{
Region: "ca-central-1",
}: endpoint{
@ -7025,6 +7070,14 @@ var awsPartition = partition{
Region: "eu-central-1",
},
},
endpointKey{
Region: "eu-central-2",
}: endpoint{
Hostname: "compute-optimizer.eu-central-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "eu-central-2",
},
},
endpointKey{
Region: "eu-north-1",
}: endpoint{
@ -7041,6 +7094,14 @@ var awsPartition = partition{
Region: "eu-south-1",
},
},
endpointKey{
Region: "eu-south-2",
}: endpoint{
Hostname: "compute-optimizer.eu-south-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "eu-south-2",
},
},
endpointKey{
Region: "eu-west-1",
}: endpoint{
@ -7065,6 +7126,22 @@ var awsPartition = partition{
Region: "eu-west-3",
},
},
endpointKey{
Region: "il-central-1",
}: endpoint{
Hostname: "compute-optimizer.il-central-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "il-central-1",
},
},
endpointKey{
Region: "me-central-1",
}: endpoint{
Hostname: "compute-optimizer.me-central-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "me-central-1",
},
},
endpointKey{
Region: "me-south-1",
}: endpoint{
@ -35257,12 +35334,42 @@ var awsusgovPartition = partition{
},
"appconfigdata": service{
Endpoints: serviceEndpoints{
endpointKey{
Region: "fips-us-gov-east-1",
}: endpoint{
Hostname: "appconfigdata.us-gov-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-east-1",
},
Deprecated: boxedTrue,
},
endpointKey{
Region: "fips-us-gov-west-1",
}: endpoint{
Hostname: "appconfigdata.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-west-1",
},
Deprecated: boxedTrue,
},
endpointKey{
Region: "us-gov-east-1",
}: endpoint{},
endpointKey{
Region: "us-gov-east-1",
Variant: fipsVariant,
}: endpoint{
Hostname: "appconfigdata.us-gov-east-1.amazonaws.com",
},
endpointKey{
Region: "us-gov-west-1",
}: endpoint{},
endpointKey{
Region: "us-gov-west-1",
Variant: fipsVariant,
}: endpoint{
Hostname: "appconfigdata.us-gov-west-1.amazonaws.com",
},
},
},
"application-autoscaling": service{

View file

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK
const SDKVersion = "1.47.9"
const SDKVersion = "1.47.11"

15
vendor/modules.txt vendored
View file

@ -110,7 +110,7 @@ github.com/VividCortex/ewma
# github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
## explicit; go 1.15
github.com/alecthomas/units
# github.com/aws/aws-sdk-go v1.47.9
# github.com/aws/aws-sdk-go v1.47.11
## explicit; go 1.19
github.com/aws/aws-sdk-go/aws
github.com/aws/aws-sdk-go/aws/auth/bearer
@ -156,7 +156,6 @@ github.com/aws/aws-sdk-go/service/sts
github.com/aws/aws-sdk-go/service/sts/stsiface
# github.com/aws/aws-sdk-go-v2 v1.22.2
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2
github.com/aws/aws-sdk-go-v2/aws
github.com/aws/aws-sdk-go-v2/aws/arn
github.com/aws/aws-sdk-go-v2/aws/defaults
@ -183,10 +182,10 @@ github.com/aws/aws-sdk-go-v2/internal/timeconv
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/eventstreamapi
# github.com/aws/aws-sdk-go-v2/config v1.23.0
# github.com/aws/aws-sdk-go-v2/config v1.25.0
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2/config
# github.com/aws/aws-sdk-go-v2/credentials v1.15.2
# github.com/aws/aws-sdk-go-v2/credentials v1.16.0
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2/credentials
github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds
@ -199,7 +198,7 @@ github.com/aws/aws-sdk-go-v2/credentials/stscreds
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2/feature/ec2/imds
github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config
# github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.5
# github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.13.7
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2/feature/s3/manager
# github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.2
@ -208,7 +207,7 @@ github.com/aws/aws-sdk-go-v2/internal/configsources
# github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.2
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2
# github.com/aws/aws-sdk-go-v2/internal/ini v1.6.0
# github.com/aws/aws-sdk-go-v2/internal/ini v1.7.0
## explicit; go 1.19
github.com/aws/aws-sdk-go-v2/internal/ini
# github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.2
@ -571,7 +570,7 @@ go.opencensus.io/trace
go.opencensus.io/trace/internal
go.opencensus.io/trace/propagation
go.opencensus.io/trace/tracestate
# go.opentelemetry.io/collector/pdata v1.0.0-rcv0017
# go.opentelemetry.io/collector/pdata v1.0.0-rcv0018
## explicit; go 1.20
go.opentelemetry.io/collector/pdata/internal
go.opentelemetry.io/collector/pdata/internal/data
@ -588,7 +587,7 @@ go.opentelemetry.io/collector/pdata/internal/otlp
go.opentelemetry.io/collector/pdata/pcommon
go.opentelemetry.io/collector/pdata/pmetric
go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp
# go.opentelemetry.io/collector/semconv v0.88.0
# go.opentelemetry.io/collector/semconv v0.89.0
## explicit; go 1.20
go.opentelemetry.io/collector/semconv/v1.6.1
# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0