diff --git a/go.mod b/go.mod index d69343c3..b498b8c2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/pluralsh/plural go 1.18 require ( - cloud.google.com/go/compute v1.15.1 + cloud.google.com/go/compute v1.18.0 cloud.google.com/go/resourcemanager v1.4.0 cloud.google.com/go/serviceusage v1.4.0 cloud.google.com/go/storage v1.27.0 @@ -20,6 +20,9 @@ require ( github.com/Azure/go-autorest/autorest/to v0.4.0 github.com/Masterminds/sprig/v3 v3.2.3 github.com/Yamashou/gqlgenc v0.11.0 + github.com/aws/aws-sdk-go-v2 v1.17.4 + github.com/aws/aws-sdk-go-v2/service/iam v1.19.2 + github.com/aws/aws-sdk-go-v2/service/sts v1.16.17 github.com/buger/goterm v1.0.4 github.com/chartmuseum/helm-push v0.10.3 github.com/coreos/go-semver v0.3.0 @@ -52,7 +55,7 @@ require ( github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 golang.org/x/crypto v0.5.0 golang.org/x/mod v0.6.0 - golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 + golang.org/x/oauth2 v0.5.0 gopkg.in/yaml.v2 v2.4.0 helm.sh/helm/v3 v3.11.0 k8s.io/api v0.26.1 @@ -64,17 +67,16 @@ require ( ) require ( - cloud.google.com/go/compute/metadata v0.2.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/longrunning v0.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a // indirect - github.com/aws/aws-sdk-go-v2 v1.16.14 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.12.18 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.22 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 // indirect @@ -83,15 +85,14 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.11.21 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.16.17 // indirect - github.com/aws/smithy-go v1.13.2 // indirect + github.com/aws/smithy-go v1.13.5 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/goccy/go-json v0.9.7 // indirect github.com/golang-jwt/jwt v3.2.1+incompatible // indirect github.com/google/gnostic v0.5.7-v3refs // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -100,13 +101,13 @@ require ( github.com/stretchr/objx v0.5.0 // indirect github.com/vektah/gqlparser/v2 v2.5.1 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect - google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd // indirect + google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( cloud.google.com/go v0.107.0 // indirect - cloud.google.com/go/iam v0.7.0 // indirect + cloud.google.com/go/iam v0.12.0 github.com/Azure/azure-pipeline-go v0.2.3 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect @@ -129,7 +130,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ec2 v1.51.1 github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2 github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/cli/browser v1.0.0 // indirect github.com/cli/safeexec v1.0.0 // indirect @@ -242,16 +243,16 @@ require ( github.com/xlab/treeprint v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - golang.org/x/net v0.5.0 // indirect + golang.org/x/net v0.6.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/term v0.4.0 - golang.org/x/text v0.6.0 + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 + golang.org/x/text v0.7.0 golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.103.0 + google.golang.org/api v0.110.0 google.golang.org/appengine v1.6.7 // indirect - google.golang.org/grpc v1.51.0 // indirect + google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index 604ece5d..57301638 100644 --- a/go.sum +++ b/go.sum @@ -26,15 +26,15 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -175,8 +175,9 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= -github.com/aws/aws-sdk-go-v2 v1.16.14 h1:db6GvO4Z2UqHt5gvT0lr6J5x5P+oQ7bdRzczVaRekMU= github.com/aws/aws-sdk-go-v2 v1.16.14/go.mod h1:s/G+UV29dECbF5rf+RNj1xhlmvoNurGSr+McVSRj59w= +github.com/aws/aws-sdk-go-v2 v1.17.4 h1:wyC6p9Yfq6V2y98wfDsj6OnNQa4w2BLGCLIxzNhwOGY= +github.com/aws/aws-sdk-go-v2 v1.17.4/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 h1:S/ZBwevQkr7gv5YxONYpGQxlMFFYSRfz3RMcjsC9Qhk= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y= github.com/aws/aws-sdk-go-v2/config v1.17.5 h1:+NS1BWvprx7nHcIk5o32LrZgifs/7Pm1V2nWjQgZ2H0= @@ -186,17 +187,21 @@ github.com/aws/aws-sdk-go-v2/credentials v1.12.18/go.mod h1:O7n/CPagQ33rfG6h7vR/ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15 h1:nkQ+aI0OCeYfzrBipL6ja/6VEbUnHQoZHBHtoK+Nzxw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15/go.mod h1:Oz2/qWINxIgSmoZT9adpxJy2UhpcOAI3TIyWgYMVSz0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21 h1:gRIXnmAVNyoRQywdNtpAkgY+f30QNzgF53Q5OobNZZs= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21/go.mod h1:XsmHMV9c512xgsW01q7H0ut+UQQQpWX8QsFbdLHDwaU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 h1:r+XwaCLpIvCKjBIYy/HVZujQS9tsz5ohHG3ZIe0wKoE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28/go.mod h1:3lwChorpIM/BhImY/hy+Z6jekmN92cXGPI1QJasVPYY= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9/go.mod h1:08tUpeSGN33QKSO7fwxXczNfiwCpbj+GxK6XKwqWVv0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15 h1:noAhOo2mMDyYhTx99aYPvQw16T3fQ/DiKAv9fzpIKH8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15/go.mod h1:kjJ4CyD9M3Wq88GYg3IPfj67Rs0Uvz8aXK7MJ8BvE4I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 h1:7AwGYXDdqRQYsluvKFmWoqpcOQJ4bH634SkYf3FNj/A= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22/go.mod h1:EqK7gVrIGAHyZItrD1D8B0ilgwMD1GiWAmbU4u/JHNk= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.22 h1:nF+E8HfYpOMw6M5oA9efB602VC00IHNQnB5CmFvZPvA= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.22/go.mod h1:tltHVGy977LrSOgRR5aV9+miyno/Gul/uJNPKS7FzP4= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6 h1:3L8pcjvgaSOs0zzZcMKzxDSkYKEpwJ2dNVDdxm68jAY= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6/go.mod h1:O7Oc4peGZDEKlddivslfYFvAbgzvl/GH3J8j3JIGBXc= github.com/aws/aws-sdk-go-v2/service/ec2 v1.51.1 h1:y88XFO3AJWDVJ3HjcYc+Oo38fB948armdg6ulfphkUM= github.com/aws/aws-sdk-go-v2/service/ec2 v1.51.1/go.mod h1:bKs78Qpk4syfUFXKhA0hIqT3X0sxmvIAPlEHV4qVbP0= +github.com/aws/aws-sdk-go-v2/service/iam v1.19.2 h1:3VWoyWLF29SjuazBalLhYM5dtk6zUpvgK/TKvaVBnjg= +github.com/aws/aws-sdk-go-v2/service/iam v1.19.2/go.mod h1:t/9Drvr/LQZAQGq83FqtuzqP66LpFo+UaMNlAOeixoc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 h1:4n4KCtv5SUoT5Er5XV41huuzrCqepxlW3SDI9qHQebc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3/go.mod h1:gkb2qADY+OHaGLKNTYxMaQNacfeyQpZ4csDTQMeFmcw= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10 h1:7LJcuRalaLw+GYQTMGmVUl4opg2HrDZkvn/L3KvIQfw= @@ -215,8 +220,9 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.3/go.mod h1:+IF75RMJh0+zqTGXG github.com/aws/aws-sdk-go-v2/service/sts v1.16.17 h1:LVM2jzEQ8mhb2dhrFl4PJ3sa5+KcKT01dsMk2Ma9/FU= github.com/aws/aws-sdk-go-v2/service/sts v1.16.17/go.mod h1:bQujK1n0V1D1Gz5uII1jaB1WDvhj4/T3tElsJnVXCR0= github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.13.2 h1:TBLKyeJfXTrTXRHmsv4qWt9IQGYyWThLYaJWSahTOGE= github.com/aws/smithy-go v1.13.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= +github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -232,8 +238,9 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/chartmuseum/helm-push v0.10.3 h1:0NQq4FJvy7gXm7nlUg2aucv7LTI5wszyI71oYm1zkzk= @@ -560,8 +567,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= @@ -1195,8 +1202,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1212,8 +1219,8 @@ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1318,14 +1325,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1338,8 +1345,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1439,8 +1446,8 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1492,8 +1499,8 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd h1:OjndDrsik+Gt+e6fs45z9AxiewiKyLKYpA45W5Kpkks= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1515,8 +1522,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/pkg/provider/aws.go b/pkg/provider/aws.go index cdba5754..2311ee54 100644 --- a/pkg/provider/aws.go +++ b/pkg/provider/aws.go @@ -2,17 +2,18 @@ package provider import ( "context" - "encoding/json" - "errors" "fmt" "os/exec" + "strings" "github.com/AlecAivazis/survey/v2" + "github.com/aws/aws-sdk-go-v2/aws" awsConfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/ec2" ec2Types "github.com/aws/aws-sdk-go-v2/service/ec2/types" "github.com/aws/aws-sdk-go-v2/service/s3" s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/aws/aws-sdk-go-v2/service/sts" v1 "k8s.io/api/core/v1" "github.com/pluralsh/plural/pkg/config" @@ -21,6 +22,9 @@ import ( "github.com/pluralsh/plural/pkg/template" "github.com/pluralsh/plural/pkg/utils" plrlErrors "github.com/pluralsh/plural/pkg/utils/errors" + + "github.com/pluralsh/plural/pkg/provider/permissions" + provUtils "github.com/pluralsh/plural/pkg/provider/utils" ) type AWSProvider struct { @@ -88,7 +92,7 @@ func mkAWS(conf config.Config) (provider *AWSProvider, err error) { return } - account, err := GetAwsAccount() + account, err := GetAwsAccount(ctx) if err != nil { err = plrlErrors.ErrorWrap(err, "Failed to get aws account (is your aws cli configured?)") return @@ -126,17 +130,20 @@ func awsFromManifest(man *manifest.ProjectManifest) (*AWSProvider, error) { } func getClient(region string, context context.Context) (*s3.Client, error) { - cfg, err := awsConfig.LoadDefaultConfig(context) - + cfg, err := getAwsConfig(context) if err != nil { - return nil, plrlErrors.ErrorWrap(err, "Failed to initialize aws client: ") + return nil, err } cfg.Region = region - return s3.NewFromConfig(cfg), nil } +func getAwsConfig(ctx context.Context) (aws.Config, error) { + cfg, err := awsConfig.LoadDefaultConfig(ctx) + return cfg, plrlErrors.ErrorWrap(err, "Failed to initialize aws client: ") +} + func (aws *AWSProvider) CreateBackend(prefix string, version string, ctx map[string]interface{}) (string, error) { if err := aws.mkBucket(aws.bucket); err != nil { return "", plrlErrors.ErrorWrap(err, fmt.Sprintf("Failed to create terraform state bucket %s", aws.bucket)) @@ -214,7 +221,9 @@ func (aws *AWSProvider) Context() map[string]interface{} { } func (aws *AWSProvider) Preflights() []*Preflight { - return nil + return []*Preflight{ + {Name: "Test IAM Permissions", Callback: aws.testIamPermissions}, + } } func (aws *AWSProvider) Flush() error { @@ -224,6 +233,10 @@ func (aws *AWSProvider) Flush() error { return aws.writer() } +func (prov *AWSProvider) Permissions() (permissions.Checker, error) { + return permissions.NewAwsChecker(*prov.goContext) +} + func (prov *AWSProvider) Decommision(node *v1.Node) error { cfg, err := awsConfig.LoadDefaultConfig(*prov.goContext) @@ -255,24 +268,38 @@ func (prov *AWSProvider) Decommision(node *v1.Node) error { return plrlErrors.ErrorWrap(err, "failed to terminate instance") } -func GetAwsAccount() (string, error) { - cmd := exec.Command("aws", "sts", "get-caller-identity") - out, err := cmd.Output() - var exitError *exec.ExitError +func GetAwsAccount(ctx context.Context) (string, error) { + cfg, err := getAwsConfig(ctx) if err != nil { - if errors.As(err, &exitError) { - return "", fmt.Errorf("error during 'aws sts get-caller-identity': %s", string(exitError.Stderr)) - } - return "", err } + svc := sts.NewFromConfig(cfg) + result, err := svc.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{}) + if err != nil { + return "", plrlErrors.ErrorWrap(err, "Error finding iam identity: ") + } - var res struct { - Account string + return *result.Account, nil +} + +func (aws *AWSProvider) testIamPermissions() error { + checker, err := aws.Permissions() + if err != nil { + return err } - if err := json.Unmarshal(out, &res); err != nil { - return "", err + missing, err := checker.MissingPermissions() + if err != nil { + return err } - return res.Account, nil + + if len(missing) == 0 { + return nil + } + + for _, missed := range missing { + provUtils.FailedPermission(missed) + } + + return fmt.Errorf("You do not meet all required iam permissions to deploy an eks cluster: %s\nThis is not necessarily a full list, we recommend using as close to AdministratorAccess as possible to run plural", strings.Join(missing, ",")) } diff --git a/pkg/provider/azure.go b/pkg/provider/azure.go index 88223e06..a4d2f7eb 100644 --- a/pkg/provider/azure.go +++ b/pkg/provider/azure.go @@ -28,6 +28,7 @@ import ( "github.com/pluralsh/plural/pkg/config" "github.com/pluralsh/plural/pkg/kubernetes" "github.com/pluralsh/plural/pkg/manifest" + "github.com/pluralsh/plural/pkg/provider/permissions" "github.com/pluralsh/plural/pkg/template" "github.com/pluralsh/plural/pkg/utils" pluralerr "github.com/pluralsh/plural/pkg/utils/errors" @@ -301,6 +302,10 @@ func (az *AzureProvider) Preflights() []*Preflight { return nil } +func (*AzureProvider) Permissions() (permissions.Checker, error) { + return permissions.NullChecker(), nil +} + func (azure *AzureProvider) Flush() error { if azure.writer == nil { return nil diff --git a/pkg/provider/equinix.go b/pkg/provider/equinix.go index a64e78af..7dbded4f 100644 --- a/pkg/provider/equinix.go +++ b/pkg/provider/equinix.go @@ -23,6 +23,7 @@ import ( metal "github.com/packethost/packngo" "github.com/pluralsh/plural/pkg/config" "github.com/pluralsh/plural/pkg/manifest" + "github.com/pluralsh/plural/pkg/provider/permissions" "github.com/pluralsh/plural/pkg/template" "github.com/pluralsh/plural/pkg/utils" pluralErrors "github.com/pluralsh/plural/pkg/utils/errors" @@ -261,6 +262,10 @@ func (equinix *EQUINIXProvider) Flush() error { return equinix.writer() } +func (*EQUINIXProvider) Permissions() (permissions.Checker, error) { + return permissions.NullChecker(), nil +} + func (prov *EQUINIXProvider) Decommision(node *v1.Node) error { client := getMetalClient(prov.Context()["ApiToken"].(string)) diff --git a/pkg/provider/gcp.go b/pkg/provider/gcp.go index cdb56005..1427983e 100644 --- a/pkg/provider/gcp.go +++ b/pkg/provider/gcp.go @@ -18,6 +18,8 @@ import ( "github.com/pluralsh/plural/pkg/config" "github.com/pluralsh/plural/pkg/kubernetes" "github.com/pluralsh/plural/pkg/manifest" + permissions "github.com/pluralsh/plural/pkg/provider/permissions" + provUtils "github.com/pluralsh/plural/pkg/provider/utils" "github.com/pluralsh/plural/pkg/template" "github.com/pluralsh/plural/pkg/utils" utilerr "github.com/pluralsh/plural/pkg/utils/errors" @@ -38,6 +40,7 @@ type GCPProvider struct { storageClient *storage.Client ctx map[string]interface{} writer manifest.Writer + projectPb *resourcemanagerpb.Project } type BucketLocation string @@ -217,7 +220,7 @@ func gcpFromManifest(man *manifest.ProjectManifest) (*GCPProvider, error) { } } - return &GCPProvider{man.Cluster, man.Project, man.Bucket, man.Region, client, man.Context, nil}, nil + return &GCPProvider{man.Cluster, man.Project, man.Bucket, man.Region, client, man.Context, nil, nil}, nil } func (gcp *GCPProvider) KubeConfig() error { @@ -340,6 +343,7 @@ func (gcp *GCPProvider) Decommision(node *v1.Node) error { func (gcp *GCPProvider) Preflights() []*Preflight { return []*Preflight{ {Name: "Enabled Services", Callback: gcp.validateEnabled}, + {Name: "Test IAM Permissions", Callback: gcp.validatePermissions}, } } @@ -383,7 +387,44 @@ func (gcp *GCPProvider) validateEnabled() error { return nil } +func (gcp *GCPProvider) Permissions() (permissions.Checker, error) { + proj, err := gcp.getProject() + if err != nil { + return nil, err + } + + return permissions.NewGcpChecker(context.Background(), proj.ProjectId) +} + +func (gcp *GCPProvider) validatePermissions() error { + ctx := context.Background() + proj, err := gcp.getProject() + if err != nil { + return err + } + + checker, _ := permissions.NewGcpChecker(ctx, proj.ProjectId) + missing, err := checker.MissingPermissions() + if err != nil { + return err + } + + if len(missing) == 0 { + return nil + } + + for _, perm := range missing { + provUtils.FailedPermission(perm) + } + + return fmt.Errorf("Your gcp identity is missing permissions for project %s; %s\nIf you aren't comfortable granting these permissions, consider creating a separate gcp project for plural resources and adding storage.admin and owner roles to your identity", proj.Name, strings.Join(missing, ", ")) +} + func (gcp *GCPProvider) getProject() (*resourcemanagerpb.Project, error) { + if gcp.projectPb != nil { + return gcp.projectPb, nil + } + ctx := context.Background() c, err := resourcemanager.NewProjectsClient(ctx) if err != nil { @@ -392,7 +433,11 @@ func (gcp *GCPProvider) getProject() (*resourcemanagerpb.Project, error) { defer func(c *resourcemanager.ProjectsClient) { _ = c.Close() }(c) - return c.GetProject(ctx, &resourcemanagerpb.GetProjectRequest{Name: fmt.Sprintf("projects/%s", gcp.Project())}) + proj, err := c.GetProject(ctx, &resourcemanagerpb.GetProjectRequest{Name: fmt.Sprintf("projects/%s", gcp.Project())}) + if err == nil { + gcp.projectPb = proj + } + return proj, err } func getInstanceAndGroupManager(ctx context.Context, c *compute.InstanceGroupManagersClient, project, zone, node string) (string, string, error) { diff --git a/pkg/provider/kind.go b/pkg/provider/kind.go index af9c93a7..ae8f9ba9 100644 --- a/pkg/provider/kind.go +++ b/pkg/provider/kind.go @@ -10,6 +10,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/pluralsh/plural/pkg/config" "github.com/pluralsh/plural/pkg/manifest" + "github.com/pluralsh/plural/pkg/provider/permissions" "github.com/pluralsh/plural/pkg/template" "github.com/pluralsh/plural/pkg/utils" "github.com/pluralsh/plural/pkg/utils/pathing" @@ -124,6 +125,10 @@ func (kind *KINDProvider) Region() string { return kind.Reg } +func (*KINDProvider) Permissions() (permissions.Checker, error) { + return permissions.NullChecker(), nil +} + func (kind *KINDProvider) Context() map[string]interface{} { return kind.ctx } diff --git a/pkg/provider/permissions/aws.go b/pkg/provider/permissions/aws.go new file mode 100644 index 00000000..302abb38 --- /dev/null +++ b/pkg/provider/permissions/aws.go @@ -0,0 +1,85 @@ +package permissions + +import ( + "context" + "regexp" + + "github.com/aws/aws-sdk-go-v2/aws" + awsConfig "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/iam" + "github.com/aws/aws-sdk-go-v2/service/iam/types" + "github.com/aws/aws-sdk-go-v2/service/sts" + plrlErrors "github.com/pluralsh/plural/pkg/utils/errors" +) + +type AwsChecker struct { + ctx context.Context + cfg aws.Config +} + +var ( + awsExpected = []string{ + "eks:CreateCluster", + "eks:CreateNodeGroup", + "eks:CreateAddOn", + "s3:CreateBucket", + "vpc:CreateVpc", + "iam:CreateRole", + "iam:CreateOpenIDConnectProvider", + } + roleRegex = regexp.MustCompile(`assumed-role/([\w+=,.@-]+)/`) +) + +func NewAwsChecker(ctx context.Context) (*AwsChecker, error) { + cfg, err := awsConfig.LoadDefaultConfig(ctx) + if err != nil { + return nil, plrlErrors.ErrorWrap(err, "could not instantiate aws client: ") + } + return &AwsChecker{ctx, cfg}, nil +} + +func (c *AwsChecker) getOriginalIdentity(arn string) (string, error) { + match := roleRegex.FindStringSubmatch(arn) + if match == nil { + return arn, nil + } + + iamSvc := iam.NewFromConfig(c.cfg) + role, err := iamSvc.GetRole(c.ctx, &iam.GetRoleInput{RoleName: aws.String(match[1])}) + if err != nil { + return "", err + } + + return *role.Role.Arn, nil +} + +func (c *AwsChecker) MissingPermissions() (result []string, err error) { + svc := sts.NewFromConfig(c.cfg) + id, err := svc.GetCallerIdentity(c.ctx, &sts.GetCallerIdentityInput{}) + if err != nil { + return + } + + iamSvc := iam.NewFromConfig(c.cfg) + arn, err := c.getOriginalIdentity(*id.Arn) + if err != nil { + return + } + + resp, err := iamSvc.SimulatePrincipalPolicy(c.ctx, &iam.SimulatePrincipalPolicyInput{ + PolicySourceArn: aws.String(arn), + ActionNames: awsExpected, + }) + if err != nil { + return + } + + result = make([]string, 0) + for _, res := range resp.EvaluationResults { + if res.EvalDecision != types.PolicyEvaluationDecisionTypeAllowed { + result = append(result, *res.EvalActionName) + } + } + + return +} diff --git a/pkg/provider/permissions/empty.go b/pkg/provider/permissions/empty.go new file mode 100644 index 00000000..932affca --- /dev/null +++ b/pkg/provider/permissions/empty.go @@ -0,0 +1,10 @@ +package permissions + +type nullChecker struct { +} + +func NullChecker() *nullChecker { return &nullChecker{} } + +func (*nullChecker) MissingPermissions() ([]string, error) { + return []string{}, nil +} diff --git a/pkg/provider/permissions/gcp.go b/pkg/provider/permissions/gcp.go new file mode 100644 index 00000000..e3a49065 --- /dev/null +++ b/pkg/provider/permissions/gcp.go @@ -0,0 +1,48 @@ +package permissions + +import ( + "context" + "fmt" + + "cloud.google.com/go/iam/apiv1/iampb" + resourcemanager "cloud.google.com/go/resourcemanager/apiv3" + "github.com/pluralsh/polly/containers" +) + +type GcpChecker struct { + project string + ctx context.Context +} + +var gcpExpected = []string{ + "storage.buckets.create", + "storage.buckets.setIamPolicy", + "iam.serviceAccounts.create", + "iam.serviceAccounts.setIamPolicy", + "container.clusters.create", + "compute.networks.create", + "compute.subnetworks.create", +} + +func NewGcpChecker(ctx context.Context, project string) (*GcpChecker, error) { + return &GcpChecker{project, ctx}, nil +} + +func (g *GcpChecker) MissingPermissions() (result []string, err error) { + svc, err := resourcemanager.NewProjectsClient(g.ctx) + if err != nil { + return + } + + res, err := svc.TestIamPermissions(g.ctx, &iampb.TestIamPermissionsRequest{ + Resource: fmt.Sprintf("projects/%s", g.project), + Permissions: gcpExpected, + }) + if err != nil { + return + } + + has := containers.ToSet(res.Permissions) + result = containers.ToSet(gcpExpected).Difference(has).List() + return +} diff --git a/pkg/provider/permissions/tester.go b/pkg/provider/permissions/tester.go new file mode 100644 index 00000000..27ad0f94 --- /dev/null +++ b/pkg/provider/permissions/tester.go @@ -0,0 +1,5 @@ +package permissions + +type Checker interface { + MissingPermissions() ([]string, error) +} diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 6e2107e8..9a050154 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -8,6 +8,7 @@ import ( "github.com/pluralsh/plural/pkg/api" "github.com/pluralsh/plural/pkg/config" "github.com/pluralsh/plural/pkg/manifest" + "github.com/pluralsh/plural/pkg/provider/permissions" "github.com/pluralsh/plural/pkg/utils" "github.com/pluralsh/polly/algorithms" v1 "k8s.io/api/core/v1" @@ -24,6 +25,7 @@ type Provider interface { Context() map[string]interface{} Decommision(node *v1.Node) error Preflights() []*Preflight + Permissions() (permissions.Checker, error) Flush() error } diff --git a/pkg/provider/utils/print.go b/pkg/provider/utils/print.go new file mode 100644 index 00000000..5873b79a --- /dev/null +++ b/pkg/provider/utils/print.go @@ -0,0 +1,10 @@ +package utils + +import ( + "github.com/pluralsh/plural/pkg/utils" +) + +func FailedPermission(perm string) { + utils.Highlight("\nRequired permission %s: ", perm) + utils.Error("failed\n") +} diff --git a/pkg/server/provider.go b/pkg/server/provider.go index 6a456ab2..40667788 100644 --- a/pkg/server/provider.go +++ b/pkg/server/provider.go @@ -2,6 +2,7 @@ package server import ( "bytes" + "context" "fmt" "os" "text/template" @@ -109,7 +110,7 @@ func setupAws(setup *SetupRequest) error { return fmt.Errorf("error configuring aws secret key: %w", err) } - accountId, err := prov.GetAwsAccount() + accountId, err := prov.GetAwsAccount(context.Background()) if err != nil { return fmt.Errorf("error getting aws account: %w", err) } diff --git a/pkg/server/setup.go b/pkg/server/setup.go index 7c3d2207..f8bd0323 100644 --- a/pkg/server/setup.go +++ b/pkg/server/setup.go @@ -11,6 +11,7 @@ import ( "github.com/pluralsh/plural/pkg/config" "github.com/pluralsh/plural/pkg/crypto" "github.com/pluralsh/plural/pkg/manifest" + "github.com/pluralsh/plural/pkg/provider" "github.com/pluralsh/plural/pkg/utils" ) @@ -140,8 +141,17 @@ func setupCli(c *gin.Context) error { } } + prov, err := provider.GetProvider() + if err != nil { + return err + } + missing, err := prov.Permissions() + if err != nil { + return err + } + // try to initialize kubeconfig if we can, but don't stress if it fails _ = execCmd("plural", "wkspace", "kube-init") - c.JSON(http.StatusOK, gin.H{"success": true}) + c.JSON(http.StatusOK, gin.H{"success": true, "missing": missing}) return nil }