Merge pull request #1770 from jedevc/integration-tests
commit
c59fc18325
@ -0,0 +1,81 @@
|
|||||||
|
name: test
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
- 'v[0-9]*'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/releases.json'
|
||||||
|
- 'README.md'
|
||||||
|
- 'docs/**'
|
||||||
|
|
||||||
|
env:
|
||||||
|
SETUP_BUILDX_VERSION: "latest"
|
||||||
|
SETUP_BUILDKIT_IMAGE: "moby/buildkit:latest"
|
||||||
|
TESTFLAGS: "-v --parallel=6 --timeout=30m"
|
||||||
|
TESTFLAGS_DOCKER: "-v --parallel=1 --timeout=30m"
|
||||||
|
GOTESTSUM_FORMAT: "standard-verbose"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
worker:
|
||||||
|
- docker
|
||||||
|
- docker-container
|
||||||
|
- remote
|
||||||
|
pkg:
|
||||||
|
- ./tests
|
||||||
|
typ:
|
||||||
|
- integration
|
||||||
|
# already run as part of build.yml
|
||||||
|
# include:
|
||||||
|
# - pkg: ./...
|
||||||
|
# skip-integration-tests: 1
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
-
|
||||||
|
name: Expose GitHub Runtime
|
||||||
|
uses: crazy-max/ghaction-github-runtime@v2
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
version: ${{ env.SETUP_BUILDX_VERSION }}
|
||||||
|
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
|
||||||
|
buildkitd-flags: --debug
|
||||||
|
-
|
||||||
|
name: Test
|
||||||
|
run: |
|
||||||
|
export TEST_REPORT_SUFFIX=-${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.skip-integration-tests }}-${{ matrix.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')
|
||||||
|
./hack/test ${{ matrix.typ }}
|
||||||
|
env:
|
||||||
|
TEST_DOCKERD: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker-container') && '1' || '0' }}"
|
||||||
|
TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker-container') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$"
|
||||||
|
TESTPKGS: "${{ matrix.pkg }}"
|
||||||
|
SKIP_INTEGRATION_TESTS: "${{ matrix.skip-integration-tests }}"
|
||||||
|
-
|
||||||
|
name: Generate annotations
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/.github/.github/actions/gotest-annotations@1a64ea6d01db9a48aa61954cb20e265782c167d9
|
||||||
|
with:
|
||||||
|
directory: ./bin/testreports
|
||||||
|
-
|
||||||
|
name: Upload test reports
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: test-reports
|
||||||
|
path: ./bin/testreports
|
@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
: "${BUILDX_CMD=docker buildx}"
|
||||||
|
: "${CACHE_FROM=}"
|
||||||
|
: "${CACHE_TO=}"
|
||||||
|
|
||||||
|
: ${TEST_INTEGRATION=}
|
||||||
|
: ${TEST_REPORT_SUFFIX=}
|
||||||
|
: ${TEST_KEEP_CACHE=}
|
||||||
|
: ${TEST_DOCKERD=}
|
||||||
|
: ${TEST_BUILDKIT_IMAGE=}
|
||||||
|
|
||||||
|
if [ -n "$CACHE_FROM" ]; then
|
||||||
|
for cfrom in $CACHE_FROM; do
|
||||||
|
setFlags+=(--set "*.cache-from=$cfrom")
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [ -n "$CACHE_TO" ]; then
|
||||||
|
for cto in $CACHE_TO; do
|
||||||
|
setFlags+=(--set "*.cache-to=$cto")
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$#" == 0 ]; then TEST_INTEGRATION=1; fi
|
||||||
|
|
||||||
|
while test $# -gt 0; do
|
||||||
|
case "$1" in
|
||||||
|
integration)
|
||||||
|
TEST_INTEGRATION=1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "unknown arg $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
iid="buildx-tests"
|
||||||
|
|
||||||
|
testReportsDir="$(pwd)/bin/testreports"
|
||||||
|
mkdir -p "$testReportsDir"
|
||||||
|
testReportsVol="-v $testReportsDir:/testreports"
|
||||||
|
gotestsumArgs="--format=standard-verbose --jsonfile=/testreports/go-test-report$TEST_REPORT_SUFFIX.json --junitfile=/testreports/junit-report$TEST_REPORT_SUFFIX.xml"
|
||||||
|
gotestArgs="-mod=vendor -coverprofile=/testreports/coverage-report$TEST_REPORT_SUFFIX.txt -covermode=atomic"
|
||||||
|
|
||||||
|
${BUILDX_CMD} bake integration-test "${setFlags[@]}" --set "*.output=type=docker,name=$iid"
|
||||||
|
|
||||||
|
cacheVolume="buildx-test-cache"
|
||||||
|
if ! docker container inspect "$cacheVolume" >/dev/null 2>/dev/null; then
|
||||||
|
docker create -v /root/.cache -v /root/.cache/registry -v /go/pkg/mod --name "$cacheVolume" alpine
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TEST_INTEGRATION" == 1 ]; then
|
||||||
|
cid=$(docker create --rm -v /tmp $testReportsVol --volumes-from=$cacheVolume -e GITHUB_REF -e TEST_DOCKERD -e TEST_BUILDKIT_IMAGE -e SKIP_INTEGRATION_TESTS -e GOTESTSUM_FORMAT ${BUILDKIT_INTEGRATION_SNAPSHOTTER:+"-eBUILDKIT_INTEGRATION_SNAPSHOTTER"} -e BUILDKIT_REGISTRY_MIRROR_DIR=/root/.cache/registry --privileged $iid gotestsum $gotestsumArgs --packages="${TESTPKGS:-./...}" -- $gotestArgs ${TESTFLAGS:--v})
|
||||||
|
docker start -a -i $cid
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TEST_KEEP_CACHE" != "1" ]; then
|
||||||
|
docker rm -v $cacheVolume
|
||||||
|
fi
|
@ -0,0 +1,102 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
|
"github.com/containerd/continuity/fs/fstest"
|
||||||
|
"github.com/moby/buildkit/util/contentutil"
|
||||||
|
"github.com/moby/buildkit/util/testutil"
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func buildCmd(sb integration.Sandbox, args ...string) (string, error) {
|
||||||
|
args = append([]string{"build", "--progress=quiet"}, args...)
|
||||||
|
cmd := buildxCmd(sb, args...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
return string(out), err
|
||||||
|
}
|
||||||
|
|
||||||
|
var buildTests = []func(t *testing.T, sb integration.Sandbox){
|
||||||
|
testBuild,
|
||||||
|
testBuildLocalExport,
|
||||||
|
testBuildRegistryExport,
|
||||||
|
testBuildTarExport,
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBuild(t *testing.T, sb integration.Sandbox) {
|
||||||
|
dir := createTestProject(t)
|
||||||
|
out, err := buildCmd(sb, dir)
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBuildLocalExport(t *testing.T, sb integration.Sandbox) {
|
||||||
|
dir := createTestProject(t)
|
||||||
|
out, err := buildCmd(sb, fmt.Sprintf("--output=type=local,dest=%s/result", dir), dir)
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
dt, err := os.ReadFile(dir + "/result/bar")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "foo", string(dt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBuildTarExport(t *testing.T, sb integration.Sandbox) {
|
||||||
|
dir := createTestProject(t)
|
||||||
|
out, err := buildCmd(sb, fmt.Sprintf("--output=type=tar,dest=%s/result.tar", dir), dir)
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
dt, err := os.ReadFile(fmt.Sprintf("%s/result.tar", dir))
|
||||||
|
require.NoError(t, err)
|
||||||
|
m, err := testutil.ReadTarToMap(dt, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Contains(t, m, "bar")
|
||||||
|
require.Equal(t, "foo", string(m["bar"].Data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBuildRegistryExport(t *testing.T, sb integration.Sandbox) {
|
||||||
|
dir := createTestProject(t)
|
||||||
|
|
||||||
|
registry, err := sb.NewRegistry()
|
||||||
|
if errors.Is(err, integration.ErrRequirements) {
|
||||||
|
t.Skip(err.Error())
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
target := registry + "/buildx/registry:latest"
|
||||||
|
|
||||||
|
out, err := buildCmd(sb, fmt.Sprintf("--output=type=image,name=%s,push=true", target), dir)
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
desc, provider, err := contentutil.ProviderFromRef(target)
|
||||||
|
require.NoError(t, err)
|
||||||
|
imgs, err := testutil.ReadImages(sb.Context(), provider, desc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
pk := platforms.Format(platforms.Normalize(platforms.DefaultSpec()))
|
||||||
|
img := imgs.Find(pk)
|
||||||
|
require.NotNil(t, img)
|
||||||
|
require.Len(t, img.Layers, 1)
|
||||||
|
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTestProject(t *testing.T) string {
|
||||||
|
dockerfile := []byte(`
|
||||||
|
FROM busybox:latest AS base
|
||||||
|
COPY foo /etc/foo
|
||||||
|
RUN cp /etc/foo /etc/bar
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
COPY --from=base /etc/bar /bar
|
||||||
|
`)
|
||||||
|
dir, err := tmpdir(
|
||||||
|
t,
|
||||||
|
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||||
|
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return dir
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func inspectCmd(sb integration.Sandbox, args ...string) (string, error) {
|
||||||
|
args = append([]string{"inspect"}, args...)
|
||||||
|
cmd := buildxCmd(sb, args...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
return string(out), err
|
||||||
|
}
|
||||||
|
|
||||||
|
var inspectTests = []func(t *testing.T, sb integration.Sandbox){
|
||||||
|
testInspect,
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInspect(t *testing.T, sb integration.Sandbox) {
|
||||||
|
out, err := inspectCmd(sb)
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
var name string
|
||||||
|
var driver string
|
||||||
|
for _, line := range strings.Split(out, "\n") {
|
||||||
|
if v, ok := strings.CutPrefix(line, "Name:"); ok && name == "" {
|
||||||
|
name = strings.TrimSpace(v)
|
||||||
|
}
|
||||||
|
if v, ok := strings.CutPrefix(line, "Driver:"); ok && driver == "" {
|
||||||
|
driver = strings.TrimSpace(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.Equal(t, sb.Address(), name)
|
||||||
|
require.Equal(t, sb.Name(), driver)
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containerd/continuity/fs/fstest"
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
)
|
||||||
|
|
||||||
|
func tmpdir(t *testing.T, appliers ...fstest.Applier) (string, error) {
|
||||||
|
tmpdir := t.TempDir()
|
||||||
|
if err := fstest.Apply(appliers...).Apply(tmpdir); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return tmpdir, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildxCmd(sb integration.Sandbox, args ...string) *exec.Cmd {
|
||||||
|
if builder := sb.Address(); builder != "" {
|
||||||
|
args = append([]string{"--builder=" + builder}, args...)
|
||||||
|
}
|
||||||
|
cmd := exec.Command("buildx", args...)
|
||||||
|
if context := sb.DockerAddress(); context != "" {
|
||||||
|
cmd.Env = append(os.Environ(), "DOCKER_CONTEXT="+context)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/distribution/distribution/v3/reference"
|
||||||
|
"github.com/docker/buildx/tests/workers"
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if integration.IsTestDockerd() {
|
||||||
|
workers.InitDockerWorker()
|
||||||
|
workers.InitDockerContainerWorker()
|
||||||
|
} else {
|
||||||
|
workers.InitRemoteWorker()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIntegration(t *testing.T) {
|
||||||
|
var tests []func(t *testing.T, sb integration.Sandbox)
|
||||||
|
tests = append(tests, buildTests...)
|
||||||
|
tests = append(tests, inspectTests...)
|
||||||
|
tests = append(tests, lsTests...)
|
||||||
|
testIntegration(t, tests...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIntegration(t *testing.T, funcs ...func(t *testing.T, sb integration.Sandbox)) {
|
||||||
|
mirroredImages := integration.OfficialImages("busybox:latest", "alpine:latest")
|
||||||
|
buildkitImage := "docker.io/moby/buildkit:buildx-stable-1"
|
||||||
|
if integration.IsTestDockerd() {
|
||||||
|
if img, ok := os.LookupEnv("TEST_BUILDKIT_IMAGE"); ok {
|
||||||
|
ref, err := reference.ParseNormalizedNamed(img)
|
||||||
|
if err == nil {
|
||||||
|
buildkitImage = ref.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mirroredImages["moby/buildkit:buildx-stable-1"] = buildkitImage
|
||||||
|
mirrors := integration.WithMirroredImages(mirroredImages)
|
||||||
|
|
||||||
|
tests := integration.TestFuncs(funcs...)
|
||||||
|
integration.Run(t, tests, mirrors)
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func lsCmd(sb integration.Sandbox, args ...string) (string, error) {
|
||||||
|
args = append([]string{"ls"}, args...)
|
||||||
|
cmd := buildxCmd(sb, args...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
return string(out), err
|
||||||
|
}
|
||||||
|
|
||||||
|
var lsTests = []func(t *testing.T, sb integration.Sandbox){
|
||||||
|
testLs,
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLs(t *testing.T, sb integration.Sandbox) {
|
||||||
|
out, err := lsCmd(sb)
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
for _, line := range strings.Split(out, "\n") {
|
||||||
|
if strings.Contains(line, sb.Address()) {
|
||||||
|
require.Contains(t, line, sb.Name())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.Fail(t, out)
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package workers
|
||||||
|
|
||||||
|
type backend struct {
|
||||||
|
builder string
|
||||||
|
context string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *backend) Address() string {
|
||||||
|
return s.builder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *backend) DockerAddress() string {
|
||||||
|
return s.context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *backend) ContainerdAddress() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *backend) Snapshotter() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *backend) Rootless() bool {
|
||||||
|
return false
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package workers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/moby/buildkit/identity"
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitDockerContainerWorker() {
|
||||||
|
integration.Register(&containerWorker{
|
||||||
|
id: "docker-container",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type containerWorker struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *containerWorker) Name() string {
|
||||||
|
return w.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *containerWorker) Rootless() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *containerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (integration.Backend, func() error, error) {
|
||||||
|
bk, bkclose, err := dockerWorker{id: w.id}.New(ctx, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return bk, bkclose, err
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "integration-container-" + identity.NewID()
|
||||||
|
cmd := exec.Command("buildx", "create",
|
||||||
|
"--bootstrap",
|
||||||
|
"--name="+name,
|
||||||
|
"--config="+cfg.ConfigFile,
|
||||||
|
"--driver=docker-container",
|
||||||
|
"--driver-opt=network=host",
|
||||||
|
)
|
||||||
|
cmd.Env = append(os.Environ(), "DOCKER_CONTEXT="+bk.DockerAddress())
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
cl := func() error {
|
||||||
|
var err error
|
||||||
|
if err1 := bkclose(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
cmd := exec.Command("buildx", "rm", "-f", name)
|
||||||
|
if err1 := cmd.Run(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &backend{
|
||||||
|
context: bk.DockerAddress(),
|
||||||
|
builder: name,
|
||||||
|
}, cl, nil
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package workers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/moby/buildkit/identity"
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitDockerWorker() {
|
||||||
|
integration.Register(&dockerWorker{
|
||||||
|
id: "docker",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type dockerWorker struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c dockerWorker) Name() string {
|
||||||
|
return c.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c dockerWorker) Rootless() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||||
|
moby := integration.Moby{
|
||||||
|
ID: c.id,
|
||||||
|
}
|
||||||
|
bk, bkclose, err := moby.New(ctx, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return bk, cl, err
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "integration-" + identity.NewID()
|
||||||
|
cmd := exec.Command("docker", "context", "create",
|
||||||
|
name,
|
||||||
|
"--docker", "host="+bk.DockerAddress(),
|
||||||
|
)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return nil, cl, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
cl = func() error {
|
||||||
|
var err error
|
||||||
|
if err1 := bkclose(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
cmd := exec.Command("docker", "context", "rm", "-f", name)
|
||||||
|
if err1 := cmd.Run(); err1 != nil {
|
||||||
|
err = errors.Wrapf(err1, "failed to remove buildx instance %s", name)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &backend{
|
||||||
|
builder: name,
|
||||||
|
context: name,
|
||||||
|
}, cl, nil
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package workers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/moby/buildkit/identity"
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitRemoteWorker() {
|
||||||
|
integration.Register(&remoteWorker{
|
||||||
|
id: "remote",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type remoteWorker struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w remoteWorker) Name() string {
|
||||||
|
return w.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w remoteWorker) Rootless() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||||
|
oci := integration.OCI{ID: w.id}
|
||||||
|
bk, bkclose, err := oci.New(ctx, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return bk, cl, err
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "integration-remote-" + identity.NewID()
|
||||||
|
cmd := exec.Command("buildx", "create",
|
||||||
|
"--bootstrap",
|
||||||
|
"--name="+name,
|
||||||
|
"--driver=remote",
|
||||||
|
bk.Address(),
|
||||||
|
)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
cl = func() error {
|
||||||
|
var err error
|
||||||
|
if err1 := bkclose(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
cmd := exec.Command("buildx", "rm", "-f", name)
|
||||||
|
if err1 := cmd.Run(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &backend{
|
||||||
|
builder: name,
|
||||||
|
}, cl, nil
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,122 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/ssooidc"
|
||||||
|
smithybearer "github.com/aws/smithy-go/auth/bearer"
|
||||||
|
)
|
||||||
|
|
||||||
|
// resolveBearerAuthToken extracts a token provider from the config sources.
|
||||||
|
//
|
||||||
|
// If an explicit bearer authentication token provider is not found the
|
||||||
|
// resolver will fallback to resolving token provider via other config sources
|
||||||
|
// such as SharedConfig.
|
||||||
|
func resolveBearerAuthToken(ctx context.Context, cfg *aws.Config, configs configs) error {
|
||||||
|
found, err := resolveBearerAuthTokenProvider(ctx, cfg, configs)
|
||||||
|
if found || err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolveBearerAuthTokenProviderChain(ctx, cfg, configs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolveBearerAuthTokenProvider extracts the first instance of
|
||||||
|
// BearerAuthTokenProvider from the config sources.
|
||||||
|
//
|
||||||
|
// The resolved BearerAuthTokenProvider will be wrapped in a cache to ensure
|
||||||
|
// the Token is only refreshed when needed. This also protects the
|
||||||
|
// TokenProvider so it can be used concurrently.
|
||||||
|
//
|
||||||
|
// Config providers used:
|
||||||
|
// * bearerAuthTokenProviderProvider
|
||||||
|
func resolveBearerAuthTokenProvider(ctx context.Context, cfg *aws.Config, configs configs) (bool, error) {
|
||||||
|
tokenProvider, found, err := getBearerAuthTokenProvider(ctx, configs)
|
||||||
|
if !found || err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
|
||||||
|
ctx, configs, tokenProvider)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveBearerAuthTokenProviderChain(ctx context.Context, cfg *aws.Config, configs configs) (err error) {
|
||||||
|
_, sharedConfig, _ := getAWSConfigSources(configs)
|
||||||
|
|
||||||
|
var provider smithybearer.TokenProvider
|
||||||
|
|
||||||
|
if sharedConfig.SSOSession != nil {
|
||||||
|
provider, err = resolveBearerAuthSSOTokenProvider(
|
||||||
|
ctx, cfg, sharedConfig.SSOSession, configs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil && provider != nil {
|
||||||
|
cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
|
||||||
|
ctx, configs, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveBearerAuthSSOTokenProvider(ctx context.Context, cfg *aws.Config, session *SSOSession, configs configs) (*ssocreds.SSOTokenProvider, error) {
|
||||||
|
ssoTokenProviderOptionsFn, found, err := getSSOTokenProviderOptions(ctx, configs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get SSOTokenProviderOptions from config sources, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var optFns []func(*ssocreds.SSOTokenProviderOptions)
|
||||||
|
if found {
|
||||||
|
optFns = append(optFns, ssoTokenProviderOptionsFn)
|
||||||
|
}
|
||||||
|
|
||||||
|
cachePath, err := ssocreds.StandardCachedTokenFilepath(session.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get SSOTokenProvider's cache path, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := ssooidc.NewFromConfig(*cfg)
|
||||||
|
provider := ssocreds.NewSSOTokenProvider(client, cachePath, optFns...)
|
||||||
|
|
||||||
|
return provider, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrapWithBearerAuthTokenCache will wrap provider with an smithy-go
|
||||||
|
// bearer/auth#TokenCache with the provided options if the provider is not
|
||||||
|
// already a TokenCache.
|
||||||
|
func wrapWithBearerAuthTokenCache(
|
||||||
|
ctx context.Context,
|
||||||
|
cfgs configs,
|
||||||
|
provider smithybearer.TokenProvider,
|
||||||
|
optFns ...func(*smithybearer.TokenCacheOptions),
|
||||||
|
) (smithybearer.TokenProvider, error) {
|
||||||
|
_, ok := provider.(*smithybearer.TokenCache)
|
||||||
|
if ok {
|
||||||
|
return provider, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenCacheConfigOptions, optionsFound, err := getBearerAuthTokenCacheOptions(ctx, cfgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := make([]func(*smithybearer.TokenCacheOptions), 0, 2+len(optFns))
|
||||||
|
opts = append(opts, func(o *smithybearer.TokenCacheOptions) {
|
||||||
|
o.RefreshBeforeExpires = 5 * time.Minute
|
||||||
|
o.RetrieveBearerTokenTimeout = 30 * time.Second
|
||||||
|
})
|
||||||
|
opts = append(opts, optFns...)
|
||||||
|
if optionsFound {
|
||||||
|
opts = append(opts, tokenCacheConfigOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
return smithybearer.NewTokenCache(provider, opts...), nil
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
//go:build !windows
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package ssocreds
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func getHomeDirectory() string {
|
|
||||||
return os.Getenv("HOME")
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package ssocreds
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func getHomeDirectory() string {
|
|
||||||
return os.Getenv("USERPROFILE")
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
package ssocreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/sha1"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/aws"
|
|
||||||
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/sso"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProviderName is the name of the provider used to specify the source of credentials.
|
|
||||||
const ProviderName = "SSOProvider"
|
|
||||||
|
|
||||||
var defaultCacheLocation func() string
|
|
||||||
|
|
||||||
func defaultCacheLocationImpl() string {
|
|
||||||
return filepath.Join(getHomeDirectory(), ".aws", "sso", "cache")
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
defaultCacheLocation = defaultCacheLocationImpl
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRoleCredentialsAPIClient is a API client that implements the GetRoleCredentials operation.
|
|
||||||
type GetRoleCredentialsAPIClient interface {
|
|
||||||
GetRoleCredentials(ctx context.Context, params *sso.GetRoleCredentialsInput, optFns ...func(*sso.Options)) (*sso.GetRoleCredentialsOutput, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Options is the Provider options structure.
|
|
||||||
type Options struct {
|
|
||||||
// The Client which is configured for the AWS Region where the AWS SSO user portal is located.
|
|
||||||
Client GetRoleCredentialsAPIClient
|
|
||||||
|
|
||||||
// The AWS account that is assigned to the user.
|
|
||||||
AccountID string
|
|
||||||
|
|
||||||
// The role name that is assigned to the user.
|
|
||||||
RoleName string
|
|
||||||
|
|
||||||
// The URL that points to the organization's AWS Single Sign-On (AWS SSO) user portal.
|
|
||||||
StartURL string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provider is an AWS credential provider that retrieves temporary AWS credentials by exchanging an SSO login token.
|
|
||||||
type Provider struct {
|
|
||||||
options Options
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new AWS Single Sign-On (AWS SSO) credential provider. The provided client is expected to be configured
|
|
||||||
// for the AWS Region where the AWS SSO user portal is located.
|
|
||||||
func New(client GetRoleCredentialsAPIClient, accountID, roleName, startURL string, optFns ...func(options *Options)) *Provider {
|
|
||||||
options := Options{
|
|
||||||
Client: client,
|
|
||||||
AccountID: accountID,
|
|
||||||
RoleName: roleName,
|
|
||||||
StartURL: startURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Provider{
|
|
||||||
options: options,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve retrieves temporary AWS credentials from the configured Amazon Single Sign-On (AWS SSO) user portal
|
|
||||||
// by exchanging the accessToken present in ~/.aws/sso/cache.
|
|
||||||
func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) {
|
|
||||||
tokenFile, err := loadTokenFile(p.options.StartURL)
|
|
||||||
if err != nil {
|
|
||||||
return aws.Credentials{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := p.options.Client.GetRoleCredentials(ctx, &sso.GetRoleCredentialsInput{
|
|
||||||
AccessToken: &tokenFile.AccessToken,
|
|
||||||
AccountId: &p.options.AccountID,
|
|
||||||
RoleName: &p.options.RoleName,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return aws.Credentials{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return aws.Credentials{
|
|
||||||
AccessKeyID: aws.ToString(output.RoleCredentials.AccessKeyId),
|
|
||||||
SecretAccessKey: aws.ToString(output.RoleCredentials.SecretAccessKey),
|
|
||||||
SessionToken: aws.ToString(output.RoleCredentials.SessionToken),
|
|
||||||
Expires: time.Unix(0, output.RoleCredentials.Expiration*int64(time.Millisecond)).UTC(),
|
|
||||||
CanExpire: true,
|
|
||||||
Source: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCacheFileName(url string) (string, error) {
|
|
||||||
hash := sha1.New()
|
|
||||||
_, err := hash.Write([]byte(url))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type rfc3339 time.Time
|
|
||||||
|
|
||||||
func (r *rfc3339) UnmarshalJSON(bytes []byte) error {
|
|
||||||
var value string
|
|
||||||
|
|
||||||
if err := json.Unmarshal(bytes, &value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
parse, err := time.Parse(time.RFC3339, value)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("expected RFC3339 timestamp: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*r = rfc3339(parse)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type token struct {
|
|
||||||
AccessToken string `json:"accessToken"`
|
|
||||||
ExpiresAt rfc3339 `json:"expiresAt"`
|
|
||||||
Region string `json:"region,omitempty"`
|
|
||||||
StartURL string `json:"startUrl,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t token) Expired() bool {
|
|
||||||
return sdk.NowTime().Round(0).After(time.Time(t.ExpiresAt))
|
|
||||||
}
|
|
||||||
|
|
||||||
// InvalidTokenError is the error type that is returned if loaded token has expired or is otherwise invalid.
|
|
||||||
// To refresh the SSO session run aws sso login with the corresponding profile.
|
|
||||||
type InvalidTokenError struct {
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *InvalidTokenError) Unwrap() error {
|
|
||||||
return i.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *InvalidTokenError) Error() string {
|
|
||||||
const msg = "the SSO session has expired or is invalid"
|
|
||||||
if i.Err == nil {
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
return msg + ": " + i.Err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadTokenFile(startURL string) (t token, err error) {
|
|
||||||
key, err := getCacheFileName(startURL)
|
|
||||||
if err != nil {
|
|
||||||
return token{}, &InvalidTokenError{Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileBytes, err := ioutil.ReadFile(filepath.Join(defaultCacheLocation(), key))
|
|
||||||
if err != nil {
|
|
||||||
return token{}, &InvalidTokenError{Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(fileBytes, &t); err != nil {
|
|
||||||
return token{}, &InvalidTokenError{Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(t.AccessToken) == 0 {
|
|
||||||
return token{}, &InvalidTokenError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.Expired() {
|
|
||||||
return token{}, &InvalidTokenError{Err: fmt.Errorf("access token is expired")}
|
|
||||||
}
|
|
||||||
|
|
||||||
return t, nil
|
|
||||||
}
|
|
@ -0,0 +1,233 @@
|
|||||||
|
package ssocreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/internal/shareddefaults"
|
||||||
|
)
|
||||||
|
|
||||||
|
var osUserHomeDur = shareddefaults.UserHomeDir
|
||||||
|
|
||||||
|
// StandardCachedTokenFilepath returns the filepath for the cached SSO token file, or
|
||||||
|
// error if unable get derive the path. Key that will be used to compute a SHA1
|
||||||
|
// value that is hex encoded.
|
||||||
|
//
|
||||||
|
// Derives the filepath using the Key as:
|
||||||
|
//
|
||||||
|
// ~/.aws/sso/cache/<sha1-hex-encoded-key>.json
|
||||||
|
func StandardCachedTokenFilepath(key string) (string, error) {
|
||||||
|
homeDir := osUserHomeDur()
|
||||||
|
if len(homeDir) == 0 {
|
||||||
|
return "", fmt.Errorf("unable to get USER's home directory for cached token")
|
||||||
|
}
|
||||||
|
hash := sha1.New()
|
||||||
|
if _, err := hash.Write([]byte(key)); err != nil {
|
||||||
|
return "", fmt.Errorf("unable to compute cached token filepath key SHA1 hash, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheFilename := strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json"
|
||||||
|
|
||||||
|
return filepath.Join(homeDir, ".aws", "sso", "cache", cacheFilename), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type tokenKnownFields struct {
|
||||||
|
AccessToken string `json:"accessToken,omitempty"`
|
||||||
|
ExpiresAt *rfc3339 `json:"expiresAt,omitempty"`
|
||||||
|
|
||||||
|
RefreshToken string `json:"refreshToken,omitempty"`
|
||||||
|
ClientID string `json:"clientId,omitempty"`
|
||||||
|
ClientSecret string `json:"clientSecret,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type token struct {
|
||||||
|
tokenKnownFields
|
||||||
|
UnknownFields map[string]interface{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t token) MarshalJSON() ([]byte, error) {
|
||||||
|
fields := map[string]interface{}{}
|
||||||
|
|
||||||
|
setTokenFieldString(fields, "accessToken", t.AccessToken)
|
||||||
|
setTokenFieldRFC3339(fields, "expiresAt", t.ExpiresAt)
|
||||||
|
|
||||||
|
setTokenFieldString(fields, "refreshToken", t.RefreshToken)
|
||||||
|
setTokenFieldString(fields, "clientId", t.ClientID)
|
||||||
|
setTokenFieldString(fields, "clientSecret", t.ClientSecret)
|
||||||
|
|
||||||
|
for k, v := range t.UnknownFields {
|
||||||
|
if _, ok := fields[k]; ok {
|
||||||
|
return nil, fmt.Errorf("unknown token field %v, duplicates known field", k)
|
||||||
|
}
|
||||||
|
fields[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(fields)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTokenFieldString(fields map[string]interface{}, key, value string) {
|
||||||
|
if value == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fields[key] = value
|
||||||
|
}
|
||||||
|
func setTokenFieldRFC3339(fields map[string]interface{}, key string, value *rfc3339) {
|
||||||
|
if value == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fields[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *token) UnmarshalJSON(b []byte) error {
|
||||||
|
var fields map[string]interface{}
|
||||||
|
if err := json.Unmarshal(b, &fields); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
t.UnknownFields = map[string]interface{}{}
|
||||||
|
|
||||||
|
for k, v := range fields {
|
||||||
|
var err error
|
||||||
|
switch k {
|
||||||
|
case "accessToken":
|
||||||
|
err = getTokenFieldString(v, &t.AccessToken)
|
||||||
|
case "expiresAt":
|
||||||
|
err = getTokenFieldRFC3339(v, &t.ExpiresAt)
|
||||||
|
case "refreshToken":
|
||||||
|
err = getTokenFieldString(v, &t.RefreshToken)
|
||||||
|
case "clientId":
|
||||||
|
err = getTokenFieldString(v, &t.ClientID)
|
||||||
|
case "clientSecret":
|
||||||
|
err = getTokenFieldString(v, &t.ClientSecret)
|
||||||
|
default:
|
||||||
|
t.UnknownFields[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("field %q, %w", k, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTokenFieldString(v interface{}, value *string) error {
|
||||||
|
var ok bool
|
||||||
|
*value, ok = v.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("expect value to be string, got %T", v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTokenFieldRFC3339(v interface{}, value **rfc3339) error {
|
||||||
|
var stringValue string
|
||||||
|
if err := getTokenFieldString(v, &stringValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeValue, err := parseRFC3339(stringValue)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = &timeValue
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCachedToken(filename string) (token, error) {
|
||||||
|
fileBytes, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return token{}, fmt.Errorf("failed to read cached SSO token file, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var t token
|
||||||
|
if err := json.Unmarshal(fileBytes, &t); err != nil {
|
||||||
|
return token{}, fmt.Errorf("failed to parse cached SSO token file, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(t.AccessToken) == 0 || t.ExpiresAt == nil || time.Time(*t.ExpiresAt).IsZero() {
|
||||||
|
return token{}, fmt.Errorf(
|
||||||
|
"cached SSO token must contain accessToken and expiresAt fields")
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeCachedToken(filename string, t token, fileMode os.FileMode) (err error) {
|
||||||
|
tmpFilename := filename + ".tmp-" + strconv.FormatInt(sdk.NowTime().UnixNano(), 10)
|
||||||
|
if err := writeCacheFile(tmpFilename, fileMode, t); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Rename(tmpFilename, filename); err != nil {
|
||||||
|
return fmt.Errorf("failed to replace old cached SSO token file, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeCacheFile(filename string, fileMode os.FileMode, t token) (err error) {
|
||||||
|
var f *os.File
|
||||||
|
f, err = os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, fileMode)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create cached SSO token file %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
closeErr := f.Close()
|
||||||
|
if err == nil && closeErr != nil {
|
||||||
|
err = fmt.Errorf("failed to close cached SSO token file, %w", closeErr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
encoder := json.NewEncoder(f)
|
||||||
|
|
||||||
|
if err = encoder.Encode(t); err != nil {
|
||||||
|
return fmt.Errorf("failed to serialize cached SSO token, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type rfc3339 time.Time
|
||||||
|
|
||||||
|
func parseRFC3339(v string) (rfc3339, error) {
|
||||||
|
parsed, err := time.Parse(time.RFC3339, v)
|
||||||
|
if err != nil {
|
||||||
|
return rfc3339{}, fmt.Errorf("expected RFC3339 timestamp: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rfc3339(parsed), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rfc3339) UnmarshalJSON(bytes []byte) (err error) {
|
||||||
|
var value string
|
||||||
|
|
||||||
|
// Use JSON unmarshal to unescape the quoted value making use of JSON's
|
||||||
|
// unquoting rules.
|
||||||
|
if err = json.Unmarshal(bytes, &value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*r, err = parseRFC3339(value)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rfc3339) MarshalJSON() ([]byte, error) {
|
||||||
|
value := time.Time(*r).Format(time.RFC3339)
|
||||||
|
|
||||||
|
// Use JSON unmarshal to unescape the quoted value making use of JSON's
|
||||||
|
// quoting rules.
|
||||||
|
return json.Marshal(value)
|
||||||
|
}
|
152
vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_credentials_provider.go
generated
vendored
152
vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_credentials_provider.go
generated
vendored
@ -0,0 +1,152 @@
|
|||||||
|
package ssocreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/sso"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProviderName is the name of the provider used to specify the source of
|
||||||
|
// credentials.
|
||||||
|
const ProviderName = "SSOProvider"
|
||||||
|
|
||||||
|
// GetRoleCredentialsAPIClient is a API client that implements the
|
||||||
|
// GetRoleCredentials operation.
|
||||||
|
type GetRoleCredentialsAPIClient interface {
|
||||||
|
GetRoleCredentials(context.Context, *sso.GetRoleCredentialsInput, ...func(*sso.Options)) (
|
||||||
|
*sso.GetRoleCredentialsOutput, error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options is the Provider options structure.
|
||||||
|
type Options struct {
|
||||||
|
// The Client which is configured for the AWS Region where the AWS SSO user
|
||||||
|
// portal is located.
|
||||||
|
Client GetRoleCredentialsAPIClient
|
||||||
|
|
||||||
|
// The AWS account that is assigned to the user.
|
||||||
|
AccountID string
|
||||||
|
|
||||||
|
// The role name that is assigned to the user.
|
||||||
|
RoleName string
|
||||||
|
|
||||||
|
// The URL that points to the organization's AWS Single Sign-On (AWS SSO)
|
||||||
|
// user portal.
|
||||||
|
StartURL string
|
||||||
|
|
||||||
|
// The filepath the cached token will be retrieved from. If unset Provider will
|
||||||
|
// use the startURL to determine the filepath at.
|
||||||
|
//
|
||||||
|
// ~/.aws/sso/cache/<sha1-hex-encoded-startURL>.json
|
||||||
|
//
|
||||||
|
// If custom cached token filepath is used, the Provider's startUrl
|
||||||
|
// parameter will be ignored.
|
||||||
|
CachedTokenFilepath string
|
||||||
|
|
||||||
|
// Used by the SSOCredentialProvider if a token configuration
|
||||||
|
// profile is used in the shared config
|
||||||
|
SSOTokenProvider *SSOTokenProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provider is an AWS credential provider that retrieves temporary AWS
|
||||||
|
// credentials by exchanging an SSO login token.
|
||||||
|
type Provider struct {
|
||||||
|
options Options
|
||||||
|
|
||||||
|
cachedTokenFilepath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new AWS Single Sign-On (AWS SSO) credential provider. The
|
||||||
|
// provided client is expected to be configured for the AWS Region where the
|
||||||
|
// AWS SSO user portal is located.
|
||||||
|
func New(client GetRoleCredentialsAPIClient, accountID, roleName, startURL string, optFns ...func(options *Options)) *Provider {
|
||||||
|
options := Options{
|
||||||
|
Client: client,
|
||||||
|
AccountID: accountID,
|
||||||
|
RoleName: roleName,
|
||||||
|
StartURL: startURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Provider{
|
||||||
|
options: options,
|
||||||
|
cachedTokenFilepath: options.CachedTokenFilepath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve retrieves temporary AWS credentials from the configured Amazon
|
||||||
|
// Single Sign-On (AWS SSO) user portal by exchanging the accessToken present
|
||||||
|
// in ~/.aws/sso/cache. However, if a token provider configuration exists
|
||||||
|
// in the shared config, then we ought to use the token provider rather then
|
||||||
|
// direct access on the cached token.
|
||||||
|
func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) {
|
||||||
|
var accessToken *string
|
||||||
|
if p.options.SSOTokenProvider != nil {
|
||||||
|
token, err := p.options.SSOTokenProvider.RetrieveBearerToken(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return aws.Credentials{}, err
|
||||||
|
}
|
||||||
|
accessToken = &token.Value
|
||||||
|
} else {
|
||||||
|
if p.cachedTokenFilepath == "" {
|
||||||
|
cachedTokenFilepath, err := StandardCachedTokenFilepath(p.options.StartURL)
|
||||||
|
if err != nil {
|
||||||
|
return aws.Credentials{}, &InvalidTokenError{Err: err}
|
||||||
|
}
|
||||||
|
p.cachedTokenFilepath = cachedTokenFilepath
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenFile, err := loadCachedToken(p.cachedTokenFilepath)
|
||||||
|
if err != nil {
|
||||||
|
return aws.Credentials{}, &InvalidTokenError{Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tokenFile.ExpiresAt == nil || sdk.NowTime().After(time.Time(*tokenFile.ExpiresAt)) {
|
||||||
|
return aws.Credentials{}, &InvalidTokenError{}
|
||||||
|
}
|
||||||
|
accessToken = &tokenFile.AccessToken
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := p.options.Client.GetRoleCredentials(ctx, &sso.GetRoleCredentialsInput{
|
||||||
|
AccessToken: accessToken,
|
||||||
|
AccountId: &p.options.AccountID,
|
||||||
|
RoleName: &p.options.RoleName,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return aws.Credentials{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return aws.Credentials{
|
||||||
|
AccessKeyID: aws.ToString(output.RoleCredentials.AccessKeyId),
|
||||||
|
SecretAccessKey: aws.ToString(output.RoleCredentials.SecretAccessKey),
|
||||||
|
SessionToken: aws.ToString(output.RoleCredentials.SessionToken),
|
||||||
|
CanExpire: true,
|
||||||
|
Expires: time.Unix(0, output.RoleCredentials.Expiration*int64(time.Millisecond)).UTC(),
|
||||||
|
Source: ProviderName,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InvalidTokenError is the error type that is returned if loaded token has
|
||||||
|
// expired or is otherwise invalid. To refresh the SSO session run AWS SSO
|
||||||
|
// login with the corresponding profile.
|
||||||
|
type InvalidTokenError struct {
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InvalidTokenError) Unwrap() error {
|
||||||
|
return i.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InvalidTokenError) Error() string {
|
||||||
|
const msg = "the SSO session has expired or is invalid"
|
||||||
|
if i.Err == nil {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
return msg + ": " + i.Err.Error()
|
||||||
|
}
|
147
vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_token_provider.go
generated
vendored
147
vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_token_provider.go
generated
vendored
@ -0,0 +1,147 @@
|
|||||||
|
package ssocreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/ssooidc"
|
||||||
|
"github.com/aws/smithy-go/auth/bearer"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateTokenAPIClient provides the interface for the SSOTokenProvider's API
|
||||||
|
// client for calling CreateToken operation to refresh the SSO token.
|
||||||
|
type CreateTokenAPIClient interface {
|
||||||
|
CreateToken(context.Context, *ssooidc.CreateTokenInput, ...func(*ssooidc.Options)) (
|
||||||
|
*ssooidc.CreateTokenOutput, error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSOTokenProviderOptions provides the options for configuring the
|
||||||
|
// SSOTokenProvider.
|
||||||
|
type SSOTokenProviderOptions struct {
|
||||||
|
// Client that can be overridden
|
||||||
|
Client CreateTokenAPIClient
|
||||||
|
|
||||||
|
// The set of API Client options to be applied when invoking the
|
||||||
|
// CreateToken operation.
|
||||||
|
ClientOptions []func(*ssooidc.Options)
|
||||||
|
|
||||||
|
// The path the file containing the cached SSO token will be read from.
|
||||||
|
// Initialized the NewSSOTokenProvider's cachedTokenFilepath parameter.
|
||||||
|
CachedTokenFilepath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSOTokenProvider provides an utility for refreshing SSO AccessTokens for
|
||||||
|
// Bearer Authentication. The SSOTokenProvider can only be used to refresh
|
||||||
|
// already cached SSO Tokens. This utility cannot perform the initial SSO
|
||||||
|
// create token.
|
||||||
|
//
|
||||||
|
// The SSOTokenProvider is not safe to use concurrently. It must be wrapped in
|
||||||
|
// a utility such as smithy-go's auth/bearer#TokenCache. The SDK's
|
||||||
|
// config.LoadDefaultConfig will automatically wrap the SSOTokenProvider with
|
||||||
|
// the smithy-go TokenCache, if the external configuration loaded configured
|
||||||
|
// for an SSO session.
|
||||||
|
//
|
||||||
|
// The initial SSO create token should be preformed with the AWS CLI before the
|
||||||
|
// Go application using the SSOTokenProvider will need to retrieve the SSO
|
||||||
|
// token. If the AWS CLI has not created the token cache file, this provider
|
||||||
|
// will return an error when attempting to retrieve the cached token.
|
||||||
|
//
|
||||||
|
// This provider will attempt to refresh the cached SSO token periodically if
|
||||||
|
// needed when RetrieveBearerToken is called.
|
||||||
|
//
|
||||||
|
// A utility such as the AWS CLI must be used to initially create the SSO
|
||||||
|
// session and cached token file.
|
||||||
|
// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
||||||
|
type SSOTokenProvider struct {
|
||||||
|
options SSOTokenProviderOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ bearer.TokenProvider = (*SSOTokenProvider)(nil)
|
||||||
|
|
||||||
|
// NewSSOTokenProvider returns an initialized SSOTokenProvider that will
|
||||||
|
// periodically refresh the SSO token cached stored in the cachedTokenFilepath.
|
||||||
|
// The cachedTokenFilepath file's content will be rewritten by the token
|
||||||
|
// provider when the token is refreshed.
|
||||||
|
//
|
||||||
|
// The client must be configured for the AWS region the SSO token was created for.
|
||||||
|
func NewSSOTokenProvider(client CreateTokenAPIClient, cachedTokenFilepath string, optFns ...func(o *SSOTokenProviderOptions)) *SSOTokenProvider {
|
||||||
|
options := SSOTokenProviderOptions{
|
||||||
|
Client: client,
|
||||||
|
CachedTokenFilepath: cachedTokenFilepath,
|
||||||
|
}
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
provider := &SSOTokenProvider{
|
||||||
|
options: options,
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetrieveBearerToken returns the SSO token stored in the cachedTokenFilepath
|
||||||
|
// the SSOTokenProvider was created with. If the token has expired
|
||||||
|
// RetrieveBearerToken will attempt to refresh it. If the token cannot be
|
||||||
|
// refreshed or is not present an error will be returned.
|
||||||
|
//
|
||||||
|
// A utility such as the AWS CLI must be used to initially create the SSO
|
||||||
|
// session and cached token file. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
||||||
|
func (p SSOTokenProvider) RetrieveBearerToken(ctx context.Context) (bearer.Token, error) {
|
||||||
|
cachedToken, err := loadCachedToken(p.options.CachedTokenFilepath)
|
||||||
|
if err != nil {
|
||||||
|
return bearer.Token{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cachedToken.ExpiresAt != nil && sdk.NowTime().After(time.Time(*cachedToken.ExpiresAt)) {
|
||||||
|
cachedToken, err = p.refreshToken(ctx, cachedToken)
|
||||||
|
if err != nil {
|
||||||
|
return bearer.Token{}, fmt.Errorf("refresh cached SSO token failed, %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expiresAt := aws.ToTime((*time.Time)(cachedToken.ExpiresAt))
|
||||||
|
return bearer.Token{
|
||||||
|
Value: cachedToken.AccessToken,
|
||||||
|
CanExpire: !expiresAt.IsZero(),
|
||||||
|
Expires: expiresAt,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SSOTokenProvider) refreshToken(ctx context.Context, cachedToken token) (token, error) {
|
||||||
|
if cachedToken.ClientSecret == "" || cachedToken.ClientID == "" || cachedToken.RefreshToken == "" {
|
||||||
|
return token{}, fmt.Errorf("cached SSO token is expired, or not present, and cannot be refreshed")
|
||||||
|
}
|
||||||
|
|
||||||
|
createResult, err := p.options.Client.CreateToken(ctx, &ssooidc.CreateTokenInput{
|
||||||
|
ClientId: &cachedToken.ClientID,
|
||||||
|
ClientSecret: &cachedToken.ClientSecret,
|
||||||
|
RefreshToken: &cachedToken.RefreshToken,
|
||||||
|
GrantType: aws.String("refresh_token"),
|
||||||
|
}, p.options.ClientOptions...)
|
||||||
|
if err != nil {
|
||||||
|
return token{}, fmt.Errorf("unable to refresh SSO token, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expiresAt := sdk.NowTime().Add(time.Duration(createResult.ExpiresIn) * time.Second)
|
||||||
|
|
||||||
|
cachedToken.AccessToken = aws.ToString(createResult.AccessToken)
|
||||||
|
cachedToken.ExpiresAt = (*rfc3339)(&expiresAt)
|
||||||
|
cachedToken.RefreshToken = aws.ToString(createResult.RefreshToken)
|
||||||
|
|
||||||
|
fileInfo, err := os.Stat(p.options.CachedTokenFilepath)
|
||||||
|
if err != nil {
|
||||||
|
return token{}, fmt.Errorf("failed to stat cached SSO token file %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = storeCachedToken(p.options.CachedTokenFilepath, cachedToken, fileInfo.Mode()); err != nil {
|
||||||
|
return token{}, fmt.Errorf("unable to cache refreshed SSO token, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachedToken, nil
|
||||||
|
}
|
6
vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/assume_role_provider.go
generated
vendored
6
vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/assume_role_provider.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go
generated
vendored
@ -1,18 +0,0 @@
|
|||||||
//go:build gofuzz
|
|
||||||
// +build gofuzz
|
|
||||||
|
|
||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Fuzz(data []byte) int {
|
|
||||||
b := bytes.NewReader(data)
|
|
||||||
|
|
||||||
if _, err := Parse(b); err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
@ -0,0 +1,47 @@
|
|||||||
|
package shareddefaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SharedCredentialsFilename returns the SDK's default file path
|
||||||
|
// for the shared credentials file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/credentials
|
||||||
|
// - Windows: %USERPROFILE%\.aws\credentials
|
||||||
|
func SharedCredentialsFilename() string {
|
||||||
|
return filepath.Join(UserHomeDir(), ".aws", "credentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigFilename returns the SDK's default file path for
|
||||||
|
// the shared config file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/config
|
||||||
|
// - Windows: %USERPROFILE%\.aws\config
|
||||||
|
func SharedConfigFilename() string {
|
||||||
|
return filepath.Join(UserHomeDir(), ".aws", "config")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserHomeDir returns the home directory for the user the process is
|
||||||
|
// running under.
|
||||||
|
func UserHomeDir() string {
|
||||||
|
// Ignore errors since we only care about Windows and *nix.
|
||||||
|
home, _ := os.UserHomeDir()
|
||||||
|
|
||||||
|
if len(home) > 0 {
|
||||||
|
return home
|
||||||
|
}
|
||||||
|
|
||||||
|
currUser, _ := user.Current()
|
||||||
|
if currUser != nil {
|
||||||
|
home = currUser.HomeDir
|
||||||
|
}
|
||||||
|
|
||||||
|
return home
|
||||||
|
}
|
80
vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md
generated
vendored
80
vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md
generated
vendored
56
vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go
generated
vendored
56
vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go
generated
vendored
@ -0,0 +1,217 @@
|
|||||||
|
# v1.14.5 (2023-03-10)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.14.4 (2023-02-22)
|
||||||
|
|
||||||
|
* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes.
|
||||||
|
|
||||||
|
# v1.14.3 (2023-02-20)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.14.2 (2023-02-15)
|
||||||
|
|
||||||
|
* **Announcement**: When receiving an error response in restJson-based services, an incorrect error type may have been returned based on the content of the response. This has been fixed via PR #2012 tracked in issue #1910.
|
||||||
|
* **Bug Fix**: Correct error type parsing for restJson services.
|
||||||
|
|
||||||
|
# v1.14.1 (2023-02-03)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.14.0 (2023-01-05)
|
||||||
|
|
||||||
|
* **Feature**: Add `ErrorCodeOverride` field to all error structs (aws/smithy-go#401).
|
||||||
|
|
||||||
|
# v1.13.11 (2022-12-19)
|
||||||
|
|
||||||
|
* No change notes available for this release.
|
||||||
|
|
||||||
|
# v1.13.10 (2022-12-15)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.9 (2022-12-02)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.8 (2022-10-24)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.7 (2022-10-21)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.6 (2022-09-30)
|
||||||
|
|
||||||
|
* **Documentation**: Documentation updates for the IAM Identity Center OIDC CLI Reference.
|
||||||
|
|
||||||
|
# v1.13.5 (2022-09-20)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.4 (2022-09-14)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.3 (2022-09-02)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.2 (2022-08-31)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.1 (2022-08-29)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.13.0 (2022-08-25)
|
||||||
|
|
||||||
|
* **Feature**: Updated required request parameters on IAM Identity Center's OIDC CreateToken action.
|
||||||
|
|
||||||
|
# v1.12.14 (2022-08-11)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.13 (2022-08-09)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.12 (2022-08-08)
|
||||||
|
|
||||||
|
* **Documentation**: Documentation updates to reflect service rename - AWS IAM Identity Center (successor to AWS Single Sign-On)
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.11 (2022-08-01)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.10 (2022-07-11)
|
||||||
|
|
||||||
|
* No change notes available for this release.
|
||||||
|
|
||||||
|
# v1.12.9 (2022-07-05)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.8 (2022-06-29)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.7 (2022-06-07)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.6 (2022-05-27)
|
||||||
|
|
||||||
|
* No change notes available for this release.
|
||||||
|
|
||||||
|
# v1.12.5 (2022-05-17)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.4 (2022-04-25)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.3 (2022-03-30)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.2 (2022-03-24)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.1 (2022-03-23)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.12.0 (2022-03-08)
|
||||||
|
|
||||||
|
* **Feature**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.11.0 (2022-02-24)
|
||||||
|
|
||||||
|
* **Feature**: API client updated
|
||||||
|
* **Feature**: Adds RetryMaxAttempts and RetryMod to API client Options. This allows the API clients' default Retryer to be configured from the shared configuration files or environment variables. Adding a new Retry mode of `Adaptive`. `Adaptive` retry mode is an experimental mode, adding client rate limiting when throttles reponses are received from an API. See [retry.AdaptiveMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AdaptiveMode) for more details, and configuration options.
|
||||||
|
* **Feature**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.10.0 (2022-01-14)
|
||||||
|
|
||||||
|
* **Feature**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.9.0 (2022-01-07)
|
||||||
|
|
||||||
|
* **Feature**: API client updated
|
||||||
|
* **Feature**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.8.2 (2021-12-02)
|
||||||
|
|
||||||
|
* **Bug Fix**: Fixes a bug that prevented aws.EndpointResolverWithOptions from being used by the service client. ([#1514](https://github.com/aws/aws-sdk-go-v2/pull/1514))
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.8.1 (2021-11-19)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.8.0 (2021-11-06)
|
||||||
|
|
||||||
|
* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically.
|
||||||
|
* **Feature**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.7.0 (2021-10-21)
|
||||||
|
|
||||||
|
* **Feature**: Updated to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.6.0 (2021-10-11)
|
||||||
|
|
||||||
|
* **Feature**: API client updated
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.5.0 (2021-09-17)
|
||||||
|
|
||||||
|
* **Feature**: Updated API client and endpoints to latest revision.
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.4.0 (2021-08-27)
|
||||||
|
|
||||||
|
* **Feature**: Updated API model to latest revision.
|
||||||
|
* **Feature**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.3.3 (2021-08-19)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.3.2 (2021-08-04)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version.
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.3.1 (2021-07-15)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.3.0 (2021-06-25)
|
||||||
|
|
||||||
|
* **Feature**: Updated `github.com/aws/smithy-go` to latest version
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.2.1 (2021-05-20)
|
||||||
|
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
||||||
|
# v1.2.0 (2021-05-14)
|
||||||
|
|
||||||
|
* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting.
|
||||||
|
* **Dependency Update**: Updated to the latest SDK module versions
|
||||||
|
|
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@ -0,0 +1,433 @@
|
|||||||
|
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||||
|
|
||||||
|
package ssooidc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws/defaults"
|
||||||
|
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws/retry"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
||||||
|
awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
|
||||||
|
internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources"
|
||||||
|
smithy "github.com/aws/smithy-go"
|
||||||
|
smithydocument "github.com/aws/smithy-go/document"
|
||||||
|
"github.com/aws/smithy-go/logging"
|
||||||
|
"github.com/aws/smithy-go/middleware"
|
||||||
|
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ServiceID = "SSO OIDC"
|
||||||
|
const ServiceAPIVersion = "2019-06-10"
|
||||||
|
|
||||||
|
// Client provides the API client to make operations call for AWS SSO OIDC.
|
||||||
|
type Client struct {
|
||||||
|
options Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns an initialized Client based on the functional options. Provide
|
||||||
|
// additional functional options to further configure the behavior of the client,
|
||||||
|
// such as changing the client's endpoint or adding custom middleware behavior.
|
||||||
|
func New(options Options, optFns ...func(*Options)) *Client {
|
||||||
|
options = options.Copy()
|
||||||
|
|
||||||
|
resolveDefaultLogger(&options)
|
||||||
|
|
||||||
|
setResolvedDefaultsMode(&options)
|
||||||
|
|
||||||
|
resolveRetryer(&options)
|
||||||
|
|
||||||
|
resolveHTTPClient(&options)
|
||||||
|
|
||||||
|
resolveHTTPSignerV4(&options)
|
||||||
|
|
||||||
|
resolveDefaultEndpointConfiguration(&options)
|
||||||
|
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
options: options,
|
||||||
|
}
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
// Set of options to modify how an operation is invoked. These apply to all
|
||||||
|
// operations invoked for this client. Use functional options on operation call to
|
||||||
|
// modify this list for per operation behavior.
|
||||||
|
APIOptions []func(*middleware.Stack) error
|
||||||
|
|
||||||
|
// Configures the events that will be sent to the configured logger.
|
||||||
|
ClientLogMode aws.ClientLogMode
|
||||||
|
|
||||||
|
// The credentials object to use when signing requests.
|
||||||
|
Credentials aws.CredentialsProvider
|
||||||
|
|
||||||
|
// The configuration DefaultsMode that the SDK should use when constructing the
|
||||||
|
// clients initial default settings.
|
||||||
|
DefaultsMode aws.DefaultsMode
|
||||||
|
|
||||||
|
// The endpoint options to be used when attempting to resolve an endpoint.
|
||||||
|
EndpointOptions EndpointResolverOptions
|
||||||
|
|
||||||
|
// The service endpoint resolver.
|
||||||
|
EndpointResolver EndpointResolver
|
||||||
|
|
||||||
|
// Signature Version 4 (SigV4) Signer
|
||||||
|
HTTPSignerV4 HTTPSignerV4
|
||||||
|
|
||||||
|
// The logger writer interface to write logging messages to.
|
||||||
|
Logger logging.Logger
|
||||||
|
|
||||||
|
// The region to send requests to. (Required)
|
||||||
|
Region string
|
||||||
|
|
||||||
|
// RetryMaxAttempts specifies the maximum number attempts an API client will call
|
||||||
|
// an operation that fails with a retryable error. A value of 0 is ignored, and
|
||||||
|
// will not be used to configure the API client created default retryer, or modify
|
||||||
|
// per operation call's retry max attempts. When creating a new API Clients this
|
||||||
|
// member will only be used if the Retryer Options member is nil. This value will
|
||||||
|
// be ignored if Retryer is not nil. If specified in an operation call's functional
|
||||||
|
// options with a value that is different than the constructed client's Options,
|
||||||
|
// the Client's Retryer will be wrapped to use the operation's specific
|
||||||
|
// RetryMaxAttempts value.
|
||||||
|
RetryMaxAttempts int
|
||||||
|
|
||||||
|
// RetryMode specifies the retry mode the API client will be created with, if
|
||||||
|
// Retryer option is not also specified. When creating a new API Clients this
|
||||||
|
// member will only be used if the Retryer Options member is nil. This value will
|
||||||
|
// be ignored if Retryer is not nil. Currently does not support per operation call
|
||||||
|
// overrides, may in the future.
|
||||||
|
RetryMode aws.RetryMode
|
||||||
|
|
||||||
|
// Retryer guides how HTTP requests should be retried in case of recoverable
|
||||||
|
// failures. When nil the API client will use a default retryer. The kind of
|
||||||
|
// default retry created by the API client can be changed with the RetryMode
|
||||||
|
// option.
|
||||||
|
Retryer aws.Retryer
|
||||||
|
|
||||||
|
// The RuntimeEnvironment configuration, only populated if the DefaultsMode is set
|
||||||
|
// to DefaultsModeAuto and is initialized using config.LoadDefaultConfig. You
|
||||||
|
// should not populate this structure programmatically, or rely on the values here
|
||||||
|
// within your applications.
|
||||||
|
RuntimeEnvironment aws.RuntimeEnvironment
|
||||||
|
|
||||||
|
// The initial DefaultsMode used when the client options were constructed. If the
|
||||||
|
// DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved
|
||||||
|
// value was at that point in time. Currently does not support per operation call
|
||||||
|
// overrides, may in the future.
|
||||||
|
resolvedDefaultsMode aws.DefaultsMode
|
||||||
|
|
||||||
|
// The HTTP client to invoke API calls with. Defaults to client's default HTTP
|
||||||
|
// implementation if nil.
|
||||||
|
HTTPClient HTTPClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAPIOptions returns a functional option for setting the Client's APIOptions
|
||||||
|
// option.
|
||||||
|
func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.APIOptions = append(o.APIOptions, optFns...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithEndpointResolver returns a functional option for setting the Client's
|
||||||
|
// EndpointResolver option.
|
||||||
|
func WithEndpointResolver(v EndpointResolver) func(*Options) {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.EndpointResolver = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPClient interface {
|
||||||
|
Do(*http.Request) (*http.Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy creates a clone where the APIOptions list is deep copied.
|
||||||
|
func (o Options) Copy() Options {
|
||||||
|
to := o
|
||||||
|
to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions))
|
||||||
|
copy(to.APIOptions, o.APIOptions)
|
||||||
|
|
||||||
|
return to
|
||||||
|
}
|
||||||
|
func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) {
|
||||||
|
ctx = middleware.ClearStackValues(ctx)
|
||||||
|
stack := middleware.NewStack(opID, smithyhttp.NewStackRequest)
|
||||||
|
options := c.options.Copy()
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(&options)
|
||||||
|
}
|
||||||
|
|
||||||
|
finalizeRetryMaxAttemptOptions(&options, *c)
|
||||||
|
|
||||||
|
finalizeClientEndpointResolverOptions(&options)
|
||||||
|
|
||||||
|
for _, fn := range stackFns {
|
||||||
|
if err := fn(stack, options); err != nil {
|
||||||
|
return nil, metadata, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fn := range options.APIOptions {
|
||||||
|
if err := fn(stack); err != nil {
|
||||||
|
return nil, metadata, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
|
||||||
|
result, metadata, err = handler.Handle(ctx, params)
|
||||||
|
if err != nil {
|
||||||
|
err = &smithy.OperationError{
|
||||||
|
ServiceID: ServiceID,
|
||||||
|
OperationName: opID,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, metadata, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type noSmithyDocumentSerde = smithydocument.NoSerde
|
||||||
|
|
||||||
|
func resolveDefaultLogger(o *Options) {
|
||||||
|
if o.Logger != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.Logger = logging.Nop{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error {
|
||||||
|
return middleware.AddSetLoggerMiddleware(stack, o.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setResolvedDefaultsMode(o *Options) {
|
||||||
|
if len(o.resolvedDefaultsMode) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var mode aws.DefaultsMode
|
||||||
|
mode.SetFromString(string(o.DefaultsMode))
|
||||||
|
|
||||||
|
if mode == aws.DefaultsModeAuto {
|
||||||
|
mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment)
|
||||||
|
}
|
||||||
|
|
||||||
|
o.resolvedDefaultsMode = mode
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFromConfig returns a new client from the provided config.
|
||||||
|
func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
|
||||||
|
opts := Options{
|
||||||
|
Region: cfg.Region,
|
||||||
|
DefaultsMode: cfg.DefaultsMode,
|
||||||
|
RuntimeEnvironment: cfg.RuntimeEnvironment,
|
||||||
|
HTTPClient: cfg.HTTPClient,
|
||||||
|
Credentials: cfg.Credentials,
|
||||||
|
APIOptions: cfg.APIOptions,
|
||||||
|
Logger: cfg.Logger,
|
||||||
|
ClientLogMode: cfg.ClientLogMode,
|
||||||
|
}
|
||||||
|
resolveAWSRetryerProvider(cfg, &opts)
|
||||||
|
resolveAWSRetryMaxAttempts(cfg, &opts)
|
||||||
|
resolveAWSRetryMode(cfg, &opts)
|
||||||
|
resolveAWSEndpointResolver(cfg, &opts)
|
||||||
|
resolveUseDualStackEndpoint(cfg, &opts)
|
||||||
|
resolveUseFIPSEndpoint(cfg, &opts)
|
||||||
|
return New(opts, optFns...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveHTTPClient(o *Options) {
|
||||||
|
var buildable *awshttp.BuildableClient
|
||||||
|
|
||||||
|
if o.HTTPClient != nil {
|
||||||
|
var ok bool
|
||||||
|
buildable, ok = o.HTTPClient.(*awshttp.BuildableClient)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buildable = awshttp.NewBuildableClient()
|
||||||
|
}
|
||||||
|
|
||||||
|
modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode)
|
||||||
|
if err == nil {
|
||||||
|
buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) {
|
||||||
|
if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok {
|
||||||
|
dialer.Timeout = dialerTimeout
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
buildable = buildable.WithTransportOptions(func(transport *http.Transport) {
|
||||||
|
if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok {
|
||||||
|
transport.TLSHandshakeTimeout = tlsHandshakeTimeout
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
o.HTTPClient = buildable
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveRetryer(o *Options) {
|
||||||
|
if o.Retryer != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(o.RetryMode) == 0 {
|
||||||
|
modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode)
|
||||||
|
if err == nil {
|
||||||
|
o.RetryMode = modeConfig.RetryMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(o.RetryMode) == 0 {
|
||||||
|
o.RetryMode = aws.RetryModeStandard
|
||||||
|
}
|
||||||
|
|
||||||
|
var standardOptions []func(*retry.StandardOptions)
|
||||||
|
if v := o.RetryMaxAttempts; v != 0 {
|
||||||
|
standardOptions = append(standardOptions, func(so *retry.StandardOptions) {
|
||||||
|
so.MaxAttempts = v
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
switch o.RetryMode {
|
||||||
|
case aws.RetryModeAdaptive:
|
||||||
|
var adaptiveOptions []func(*retry.AdaptiveModeOptions)
|
||||||
|
if len(standardOptions) != 0 {
|
||||||
|
adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) {
|
||||||
|
ao.StandardOptions = append(ao.StandardOptions, standardOptions...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...)
|
||||||
|
|
||||||
|
default:
|
||||||
|
o.Retryer = retry.NewStandard(standardOptions...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveAWSRetryerProvider(cfg aws.Config, o *Options) {
|
||||||
|
if cfg.Retryer == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.Retryer = cfg.Retryer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveAWSRetryMode(cfg aws.Config, o *Options) {
|
||||||
|
if len(cfg.RetryMode) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.RetryMode = cfg.RetryMode
|
||||||
|
}
|
||||||
|
func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) {
|
||||||
|
if cfg.RetryMaxAttempts == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.RetryMaxAttempts = cfg.RetryMaxAttempts
|
||||||
|
}
|
||||||
|
|
||||||
|
func finalizeRetryMaxAttemptOptions(o *Options, client Client) {
|
||||||
|
if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveAWSEndpointResolver(cfg aws.Config, o *Options) {
|
||||||
|
if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver())
|
||||||
|
}
|
||||||
|
|
||||||
|
func addClientUserAgent(stack *middleware.Stack) error {
|
||||||
|
return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ssooidc", goModuleVersion)(stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error {
|
||||||
|
mw := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{
|
||||||
|
CredentialsProvider: o.Credentials,
|
||||||
|
Signer: o.HTTPSignerV4,
|
||||||
|
LogSigning: o.ClientLogMode.IsSigning(),
|
||||||
|
})
|
||||||
|
return stack.Finalize.Add(mw, middleware.After)
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPSignerV4 interface {
|
||||||
|
SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveHTTPSignerV4(o *Options) {
|
||||||
|
if o.HTTPSignerV4 != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.HTTPSignerV4 = newDefaultV4Signer(*o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDefaultV4Signer(o Options) *v4.Signer {
|
||||||
|
return v4.NewSigner(func(so *v4.SignerOptions) {
|
||||||
|
so.Logger = o.Logger
|
||||||
|
so.LogSigning = o.ClientLogMode.IsSigning()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func addRetryMiddlewares(stack *middleware.Stack, o Options) error {
|
||||||
|
mo := retry.AddRetryMiddlewaresOptions{
|
||||||
|
Retryer: o.Retryer,
|
||||||
|
LogRetryAttempts: o.ClientLogMode.IsRetries(),
|
||||||
|
}
|
||||||
|
return retry.AddRetryMiddlewares(stack, mo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolves dual-stack endpoint configuration
|
||||||
|
func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error {
|
||||||
|
if len(cfg.ConfigSources) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
o.EndpointOptions.UseDualStackEndpoint = value
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolves FIPS endpoint configuration
|
||||||
|
func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error {
|
||||||
|
if len(cfg.ConfigSources) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
o.EndpointOptions.UseFIPSEndpoint = value
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error {
|
||||||
|
return awsmiddleware.AddRequestIDRetrieverMiddleware(stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addResponseErrorMiddleware(stack *middleware.Stack) error {
|
||||||
|
return awshttp.AddResponseErrorMiddleware(stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addRequestResponseLogging(stack *middleware.Stack, o Options) error {
|
||||||
|
return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{
|
||||||
|
LogRequest: o.ClientLogMode.IsRequest(),
|
||||||
|
LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(),
|
||||||
|
LogResponse: o.ClientLogMode.IsResponse(),
|
||||||
|
LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(),
|
||||||
|
}, middleware.After)
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||||
|
|
||||||
|
package ssooidc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||||
|
"github.com/aws/smithy-go/middleware"
|
||||||
|
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Creates and returns an access token for the authorized client. The access token
|
||||||
|
// issued will be used to fetch short-term credentials for the assigned roles in
|
||||||
|
// the AWS account.
|
||||||
|
func (c *Client) CreateToken(ctx context.Context, params *CreateTokenInput, optFns ...func(*Options)) (*CreateTokenOutput, error) {
|
||||||
|
if params == nil {
|
||||||
|
params = &CreateTokenInput{}
|
||||||
|
}
|
||||||
|
|
||||||
|
result, metadata, err := c.invokeOperation(ctx, "CreateToken", params, optFns, c.addOperationCreateTokenMiddlewares)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := result.(*CreateTokenOutput)
|
||||||
|
out.ResultMetadata = metadata
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateTokenInput struct {
|
||||||
|
|
||||||
|
// The unique identifier string for each client. This value should come from the
|
||||||
|
// persisted result of the RegisterClient API.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
ClientId *string
|
||||||
|
|
||||||
|
// A secret string generated for the client. This value should come from the
|
||||||
|
// persisted result of the RegisterClient API.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
ClientSecret *string
|
||||||
|
|
||||||
|
// Supports grant types for the authorization code, refresh token, and device code
|
||||||
|
// request. For device code requests, specify the following value:
|
||||||
|
// urn:ietf:params:oauth:grant-type:device_code For information about how to
|
||||||
|
// obtain the device code, see the StartDeviceAuthorization topic.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
GrantType *string
|
||||||
|
|
||||||
|
// The authorization code received from the authorization service. This parameter
|
||||||
|
// is required to perform an authorization grant request to get access to a token.
|
||||||
|
Code *string
|
||||||
|
|
||||||
|
// Used only when calling this API for the device code grant type. This short-term
|
||||||
|
// code is used to identify this authentication attempt. This should come from an
|
||||||
|
// in-memory reference to the result of the StartDeviceAuthorization API.
|
||||||
|
DeviceCode *string
|
||||||
|
|
||||||
|
// The location of the application that will receive the authorization code. Users
|
||||||
|
// authorize the service to send the request to this location.
|
||||||
|
RedirectUri *string
|
||||||
|
|
||||||
|
// Currently, refreshToken is not yet implemented and is not supported. For more
|
||||||
|
// information about the features and limitations of the current IAM Identity
|
||||||
|
// Center OIDC implementation, see Considerations for Using this Guide in the IAM
|
||||||
|
// Identity Center OIDC API Reference
|
||||||
|
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html).
|
||||||
|
// The token used to obtain an access token in the event that the access token is
|
||||||
|
// invalid or expired.
|
||||||
|
RefreshToken *string
|
||||||
|
|
||||||
|
// The list of scopes that is defined by the client. Upon authorization, this list
|
||||||
|
// is used to restrict permissions when granting an access token.
|
||||||
|
Scope []string
|
||||||
|
|
||||||
|
noSmithyDocumentSerde
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateTokenOutput struct {
|
||||||
|
|
||||||
|
// An opaque token to access IAM Identity Center resources assigned to a user.
|
||||||
|
AccessToken *string
|
||||||
|
|
||||||
|
// Indicates the time in seconds when an access token will expire.
|
||||||
|
ExpiresIn int32
|
||||||
|
|
||||||
|
// Currently, idToken is not yet implemented and is not supported. For more
|
||||||
|
// information about the features and limitations of the current IAM Identity
|
||||||
|
// Center OIDC implementation, see Considerations for Using this Guide in the IAM
|
||||||
|
// Identity Center OIDC API Reference
|
||||||
|
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html).
|
||||||
|
// The identifier of the user that associated with the access token, if present.
|
||||||
|
IdToken *string
|
||||||
|
|
||||||
|
// Currently, refreshToken is not yet implemented and is not supported. For more
|
||||||
|
// information about the features and limitations of the current IAM Identity
|
||||||
|
// Center OIDC implementation, see Considerations for Using this Guide in the IAM
|
||||||
|
// Identity Center OIDC API Reference
|
||||||
|
// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html).
|
||||||
|
// A token that, if present, can be used to refresh a previously issued access
|
||||||
|
// token that might have expired.
|
||||||
|
RefreshToken *string
|
||||||
|
|
||||||
|
// Used to notify the client that the returned token is an access token. The
|
||||||
|
// supported type is BearerToken.
|
||||||
|
TokenType *string
|
||||||
|
|
||||||
|
// Metadata pertaining to the operation's result.
|
||||||
|
ResultMetadata middleware.Metadata
|
||||||
|
|
||||||
|
noSmithyDocumentSerde
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, options Options) (err error) {
|
||||||
|
err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateToken{}, middleware.After)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateToken{}, middleware.After)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addSetLoggerMiddleware(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addResolveEndpointMiddleware(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRetryMiddlewares(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addClientUserAgent(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addOpCreateTokenValidationMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateToken(options.Region), middleware.Before); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRequestIDRetrieverMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addResponseErrorMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRequestResponseLogging(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServiceMetadataMiddleware_opCreateToken(region string) *awsmiddleware.RegisterServiceMetadata {
|
||||||
|
return &awsmiddleware.RegisterServiceMetadata{
|
||||||
|
Region: region,
|
||||||
|
ServiceID: ServiceID,
|
||||||
|
OperationName: "CreateToken",
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||||
|
|
||||||
|
package ssooidc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||||
|
"github.com/aws/smithy-go/middleware"
|
||||||
|
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Registers a client with IAM Identity Center. This allows clients to initiate
|
||||||
|
// device authorization. The output should be persisted for reuse through many
|
||||||
|
// authentication requests.
|
||||||
|
func (c *Client) RegisterClient(ctx context.Context, params *RegisterClientInput, optFns ...func(*Options)) (*RegisterClientOutput, error) {
|
||||||
|
if params == nil {
|
||||||
|
params = &RegisterClientInput{}
|
||||||
|
}
|
||||||
|
|
||||||
|
result, metadata, err := c.invokeOperation(ctx, "RegisterClient", params, optFns, c.addOperationRegisterClientMiddlewares)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := result.(*RegisterClientOutput)
|
||||||
|
out.ResultMetadata = metadata
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterClientInput struct {
|
||||||
|
|
||||||
|
// The friendly name of the client.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
ClientName *string
|
||||||
|
|
||||||
|
// The type of client. The service supports only public as a client type. Anything
|
||||||
|
// other than public will be rejected by the service.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
ClientType *string
|
||||||
|
|
||||||
|
// The list of scopes that are defined by the client. Upon authorization, this list
|
||||||
|
// is used to restrict permissions when granting an access token.
|
||||||
|
Scopes []string
|
||||||
|
|
||||||
|
noSmithyDocumentSerde
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterClientOutput struct {
|
||||||
|
|
||||||
|
// The endpoint where the client can request authorization.
|
||||||
|
AuthorizationEndpoint *string
|
||||||
|
|
||||||
|
// The unique identifier string for each client. This client uses this identifier
|
||||||
|
// to get authenticated by the service in subsequent calls.
|
||||||
|
ClientId *string
|
||||||
|
|
||||||
|
// Indicates the time at which the clientId and clientSecret were issued.
|
||||||
|
ClientIdIssuedAt int64
|
||||||
|
|
||||||
|
// A secret string generated for the client. The client will use this string to get
|
||||||
|
// authenticated by the service in subsequent calls.
|
||||||
|
ClientSecret *string
|
||||||
|
|
||||||
|
// Indicates the time at which the clientId and clientSecret will become invalid.
|
||||||
|
ClientSecretExpiresAt int64
|
||||||
|
|
||||||
|
// The endpoint where the client can get an access token.
|
||||||
|
TokenEndpoint *string
|
||||||
|
|
||||||
|
// Metadata pertaining to the operation's result.
|
||||||
|
ResultMetadata middleware.Metadata
|
||||||
|
|
||||||
|
noSmithyDocumentSerde
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, options Options) (err error) {
|
||||||
|
err = stack.Serialize.Add(&awsRestjson1_serializeOpRegisterClient{}, middleware.After)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = stack.Deserialize.Add(&awsRestjson1_deserializeOpRegisterClient{}, middleware.After)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addSetLoggerMiddleware(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addResolveEndpointMiddleware(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRetryMiddlewares(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addClientUserAgent(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addOpRegisterClientValidationMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRegisterClient(options.Region), middleware.Before); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRequestIDRetrieverMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addResponseErrorMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRequestResponseLogging(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServiceMetadataMiddleware_opRegisterClient(region string) *awsmiddleware.RegisterServiceMetadata {
|
||||||
|
return &awsmiddleware.RegisterServiceMetadata{
|
||||||
|
Region: region,
|
||||||
|
ServiceID: ServiceID,
|
||||||
|
OperationName: "RegisterClient",
|
||||||
|
}
|
||||||
|
}
|
150
vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go
generated
vendored
150
vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go
generated
vendored
@ -0,0 +1,150 @@
|
|||||||
|
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||||
|
|
||||||
|
package ssooidc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||||
|
"github.com/aws/smithy-go/middleware"
|
||||||
|
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Initiates device authorization by requesting a pair of verification codes from
|
||||||
|
// the authorization service.
|
||||||
|
func (c *Client) StartDeviceAuthorization(ctx context.Context, params *StartDeviceAuthorizationInput, optFns ...func(*Options)) (*StartDeviceAuthorizationOutput, error) {
|
||||||
|
if params == nil {
|
||||||
|
params = &StartDeviceAuthorizationInput{}
|
||||||
|
}
|
||||||
|
|
||||||
|
result, metadata, err := c.invokeOperation(ctx, "StartDeviceAuthorization", params, optFns, c.addOperationStartDeviceAuthorizationMiddlewares)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := result.(*StartDeviceAuthorizationOutput)
|
||||||
|
out.ResultMetadata = metadata
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type StartDeviceAuthorizationInput struct {
|
||||||
|
|
||||||
|
// The unique identifier string for the client that is registered with IAM Identity
|
||||||
|
// Center. This value should come from the persisted result of the RegisterClient
|
||||||
|
// API operation.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
ClientId *string
|
||||||
|
|
||||||
|
// A secret string that is generated for the client. This value should come from
|
||||||
|
// the persisted result of the RegisterClient API operation.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
ClientSecret *string
|
||||||
|
|
||||||
|
// The URL for the AWS access portal. For more information, see Using the AWS
|
||||||
|
// access portal
|
||||||
|
// (https://docs.aws.amazon.com/singlesignon/latest/userguide/using-the-portal.html)
|
||||||
|
// in the IAM Identity Center User Guide.
|
||||||
|
//
|
||||||
|
// This member is required.
|
||||||
|
StartUrl *string
|
||||||
|
|
||||||
|
noSmithyDocumentSerde
|
||||||
|
}
|
||||||
|
|
||||||
|
type StartDeviceAuthorizationOutput struct {
|
||||||
|
|
||||||
|
// The short-lived code that is used by the device when polling for a session
|
||||||
|
// token.
|
||||||
|
DeviceCode *string
|
||||||
|
|
||||||
|
// Indicates the number of seconds in which the verification code will become
|
||||||
|
// invalid.
|
||||||
|
ExpiresIn int32
|
||||||
|
|
||||||
|
// Indicates the number of seconds the client must wait between attempts when
|
||||||
|
// polling for a session.
|
||||||
|
Interval int32
|
||||||
|
|
||||||
|
// A one-time user verification code. This is needed to authorize an in-use device.
|
||||||
|
UserCode *string
|
||||||
|
|
||||||
|
// The URI of the verification page that takes the userCode to authorize the
|
||||||
|
// device.
|
||||||
|
VerificationUri *string
|
||||||
|
|
||||||
|
// An alternate URL that the client can use to automatically launch a browser. This
|
||||||
|
// process skips the manual step in which the user visits the verification page and
|
||||||
|
// enters their code.
|
||||||
|
VerificationUriComplete *string
|
||||||
|
|
||||||
|
// Metadata pertaining to the operation's result.
|
||||||
|
ResultMetadata middleware.Metadata
|
||||||
|
|
||||||
|
noSmithyDocumentSerde
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middleware.Stack, options Options) (err error) {
|
||||||
|
err = stack.Serialize.Add(&awsRestjson1_serializeOpStartDeviceAuthorization{}, middleware.After)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = stack.Deserialize.Add(&awsRestjson1_deserializeOpStartDeviceAuthorization{}, middleware.After)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addSetLoggerMiddleware(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addResolveEndpointMiddleware(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRetryMiddlewares(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addClientUserAgent(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addOpStartDeviceAuthorizationValidationMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartDeviceAuthorization(options.Region), middleware.Before); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRequestIDRetrieverMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addResponseErrorMiddleware(stack); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRequestResponseLogging(stack, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServiceMetadataMiddleware_opStartDeviceAuthorization(region string) *awsmiddleware.RegisterServiceMetadata {
|
||||||
|
return &awsmiddleware.RegisterServiceMetadata{
|
||||||
|
Region: region,
|
||||||
|
ServiceID: ServiceID,
|
||||||
|
OperationName: "StartDeviceAuthorization",
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,200 @@
|
|||||||
|
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||||
|
|
||||||
|
package ssooidc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||||
|
internalendpoints "github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints"
|
||||||
|
"github.com/aws/smithy-go/middleware"
|
||||||
|
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EndpointResolverOptions is the service endpoint resolver options
|
||||||
|
type EndpointResolverOptions = internalendpoints.Options
|
||||||
|
|
||||||
|
// EndpointResolver interface for resolving service endpoints.
|
||||||
|
type EndpointResolver interface {
|
||||||
|
ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ EndpointResolver = &internalendpoints.Resolver{}
|
||||||
|
|
||||||
|
// NewDefaultEndpointResolver constructs a new service endpoint resolver
|
||||||
|
func NewDefaultEndpointResolver() *internalendpoints.Resolver {
|
||||||
|
return internalendpoints.New()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointResolverFunc is a helper utility that wraps a function so it satisfies
|
||||||
|
// the EndpointResolver interface. This is useful when you want to add additional
|
||||||
|
// endpoint resolving logic, or stub out specific endpoints with custom values.
|
||||||
|
type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error)
|
||||||
|
|
||||||
|
func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
|
||||||
|
return fn(region, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveDefaultEndpointConfiguration(o *Options) {
|
||||||
|
if o.EndpointResolver != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.EndpointResolver = NewDefaultEndpointResolver()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointResolverFromURL returns an EndpointResolver configured using the
|
||||||
|
// provided endpoint url. By default, the resolved endpoint resolver uses the
|
||||||
|
// client region as signing region, and the endpoint source is set to
|
||||||
|
// EndpointSourceCustom.You can provide functional options to configure endpoint
|
||||||
|
// values for the resolved endpoint.
|
||||||
|
func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver {
|
||||||
|
e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom}
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(&e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return EndpointResolverFunc(
|
||||||
|
func(region string, options EndpointResolverOptions) (aws.Endpoint, error) {
|
||||||
|
if len(e.SigningRegion) == 0 {
|
||||||
|
e.SigningRegion = region
|
||||||
|
}
|
||||||
|
return e, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResolveEndpoint struct {
|
||||||
|
Resolver EndpointResolver
|
||||||
|
Options EndpointResolverOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ResolveEndpoint) ID() string {
|
||||||
|
return "ResolveEndpoint"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
|
||||||
|
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
|
||||||
|
) {
|
||||||
|
req, ok := in.Request.(*smithyhttp.Request)
|
||||||
|
if !ok {
|
||||||
|
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Resolver == nil {
|
||||||
|
return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
eo := m.Options
|
||||||
|
eo.Logger = middleware.GetLogger(ctx)
|
||||||
|
|
||||||
|
var endpoint aws.Endpoint
|
||||||
|
endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo)
|
||||||
|
if err != nil {
|
||||||
|
return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.URL, err = url.Parse(endpoint.URL)
|
||||||
|
if err != nil {
|
||||||
|
return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(awsmiddleware.GetSigningName(ctx)) == 0 {
|
||||||
|
signingName := endpoint.SigningName
|
||||||
|
if len(signingName) == 0 {
|
||||||
|
signingName = "awsssooidc"
|
||||||
|
}
|
||||||
|
ctx = awsmiddleware.SetSigningName(ctx, signingName)
|
||||||
|
}
|
||||||
|
ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source)
|
||||||
|
ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable)
|
||||||
|
ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion)
|
||||||
|
ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID)
|
||||||
|
return next.HandleSerialize(ctx, in)
|
||||||
|
}
|
||||||
|
func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error {
|
||||||
|
return stack.Serialize.Insert(&ResolveEndpoint{
|
||||||
|
Resolver: o.EndpointResolver,
|
||||||
|
Options: o.EndpointOptions,
|
||||||
|
}, "OperationSerializer", middleware.Before)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeResolveEndpointMiddleware(stack *middleware.Stack) error {
|
||||||
|
_, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type wrappedEndpointResolver struct {
|
||||||
|
awsResolver aws.EndpointResolverWithOptions
|
||||||
|
resolver EndpointResolver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
|
||||||
|
if w.awsResolver == nil {
|
||||||
|
goto fallback
|
||||||
|
}
|
||||||
|
endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options)
|
||||||
|
if err == nil {
|
||||||
|
return endpoint, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) {
|
||||||
|
return endpoint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
if w.resolver == nil {
|
||||||
|
return endpoint, fmt.Errorf("default endpoint resolver provided was nil")
|
||||||
|
}
|
||||||
|
return w.resolver.ResolveEndpoint(region, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error)
|
||||||
|
|
||||||
|
func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) {
|
||||||
|
return a(service, region)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil)
|
||||||
|
|
||||||
|
// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver.
|
||||||
|
// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided
|
||||||
|
// fallbackResolver for resolution.
|
||||||
|
//
|
||||||
|
// fallbackResolver must not be nil
|
||||||
|
func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver {
|
||||||
|
var resolver aws.EndpointResolverWithOptions
|
||||||
|
|
||||||
|
if awsResolverWithOptions != nil {
|
||||||
|
resolver = awsResolverWithOptions
|
||||||
|
} else if awsResolver != nil {
|
||||||
|
resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &wrappedEndpointResolver{
|
||||||
|
awsResolver: resolver,
|
||||||
|
resolver: fallbackResolver,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func finalizeClientEndpointResolverOptions(options *Options) {
|
||||||
|
options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage()
|
||||||
|
|
||||||
|
if len(options.EndpointOptions.ResolvedRegion) == 0 {
|
||||||
|
const fipsInfix = "-fips-"
|
||||||
|
const fipsPrefix = "fips-"
|
||||||
|
const fipsSuffix = "-fips"
|
||||||
|
|
||||||
|
if strings.Contains(options.Region, fipsInfix) ||
|
||||||
|
strings.Contains(options.Region, fipsPrefix) ||
|
||||||
|
strings.Contains(options.Region, fipsSuffix) {
|
||||||
|
options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
|
||||||
|
options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "")
|
||||||
|
options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"github.com/aws/aws-sdk-go-v2": "v1.4.0",
|
||||||
|
"github.com/aws/aws-sdk-go-v2/internal/configsources": "v0.0.0-00010101000000-000000000000",
|
||||||
|
"github.com/aws/aws-sdk-go-v2/internal/endpoints/v2": "v2.0.0-00010101000000-000000000000",
|
||||||
|
"github.com/aws/smithy-go": "v1.4.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"api_client.go",
|
||||||
|
"api_client_test.go",
|
||||||
|
"api_op_CreateToken.go",
|
||||||
|
"api_op_RegisterClient.go",
|
||||||
|
"api_op_StartDeviceAuthorization.go",
|
||||||
|
"deserializers.go",
|
||||||
|
"doc.go",
|
||||||
|
"endpoints.go",
|
||||||
|
"generated.json",
|
||||||
|
"internal/endpoints/endpoints.go",
|
||||||
|
"internal/endpoints/endpoints_test.go",
|
||||||
|
"protocol_test.go",
|
||||||
|
"serializers.go",
|
||||||
|
"types/errors.go",
|
||||||
|
"types/types.go",
|
||||||
|
"validators.go"
|
||||||
|
],
|
||||||
|
"go": "1.15",
|
||||||
|
"module": "github.com/aws/aws-sdk-go-v2/service/ssooidc",
|
||||||
|
"unstable": false
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT.
|
||||||
|
|
||||||
|
package ssooidc
|
||||||
|
|
||||||
|
// goModuleVersion is the tagged release for this module
|
||||||
|
const goModuleVersion = "1.14.5"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue