From deb083b53082dc73be7a9be400d06ee972e9261c Mon Sep 17 00:00:00 2001 From: Naadir Jeewa Date: Wed, 3 Nov 2021 19:17:55 +0000 Subject: [PATCH] Extend AWS CloudFormation commands Adds support for enabling TMC integration using ENABLE_TMC_CLOUD_PROVIDER_PERMISSIONS=true as well as adding the generate-cloudformation-template subcommand to `management-cluster permissions aws`, which will allow users to apply CloudFormation by themselves, or convert the template into IAM policies or Terraform. Signed-off-by: Naadir Jeewa --- addons/go.sum | 87 ----- .../permissions_aws_generate.go | 36 ++ .../managementcluster/permissions_aws_set.go | 4 +- go.mod | 2 + pkg/v1/providers/config_default.yaml | 3 + pkg/v1/tkg/aws/client.go | 75 +++- pkg/v1/tkg/aws/client_test.go | 59 ++- .../aws/fixtures/cloudformation-default.yaml | 295 +++++++++++++++ .../aws/fixtures/cloudformation-with-tmc.yaml | 329 +++++++++++++++++ pkg/v1/tkg/aws/interface.go | 4 + pkg/v1/tkg/client/client.go | 2 + pkg/v1/tkg/client/config_permission.go | 47 ++- pkg/v1/tkg/constants/config_variables.go | 17 +- pkg/v1/tkg/fakes/awsclient.go | 155 ++++++++ pkg/v1/tkg/fakes/client.go | 70 ++++ pkg/v1/tkg/fakes/featuresclient.go | 339 ++++++++++++++++++ pkg/v1/tkg/tkgctl/config_permission_aws.go | 13 +- pkg/v1/tkg/tkgctl/interface.go | 2 + 18 files changed, 1426 insertions(+), 113 deletions(-) create mode 100644 cmd/cli/plugin/managementcluster/permissions_aws_generate.go create mode 100644 pkg/v1/tkg/aws/fixtures/cloudformation-default.yaml create mode 100644 pkg/v1/tkg/aws/fixtures/cloudformation-with-tmc.yaml create mode 100644 pkg/v1/tkg/fakes/featuresclient.go diff --git a/addons/go.sum b/addons/go.sum index 127a711c99..0679f20a15 100644 --- a/addons/go.sum +++ b/addons/go.sum @@ -26,7 +26,6 @@ cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0 h1:bAMqZidYkmIsUqe6PtkEPT7Q+vfizScn+jfNA6jwK9c= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= @@ -63,7 +62,6 @@ contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0Wk contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AlecAivazis/survey/v2 v2.1.1/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk= -github.com/Azure/aad-pod-identity v1.8.0/go.mod h1:z1+AHOskemFNCHmSdtF3DMqw6mBb/Va7/wLY9+4Aauk= github.com/Azure/aad-pod-identity v1.8.5/go.mod h1:mu0fepT2bK9Te2VNlKPy9qEFSgdFZXM3pblQ/9cMWhg= github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= @@ -73,11 +71,8 @@ github.com/Azure/azure-sdk-for-go v29.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v40.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v55.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v57.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v58.1.0+incompatible h1:WFsr3Efy7uweykOAEfOHO3ACtuwIv+rrFmSn9K48VnA= github.com/Azure/azure-sdk-for-go v58.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= @@ -95,8 +90,6 @@ github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8 github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.9/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest v0.11.21/go.mod h1:Do/yuMSW/13ayUkcVREpsMHGG+MvV81uzSCFgYPj4tM= @@ -114,7 +107,6 @@ github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4Uw github.com/Azure/go-autorest/autorest/adal v0.9.16/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM= github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.3/go.mod h1:4bJZhUhcq8LB20TruwHbAQsmUs2Xh+QR7utuJpLXX3A= github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U= github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= @@ -132,7 +124,6 @@ github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsI github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= @@ -486,8 +477,6 @@ github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B github.com/coredns/caddy v1.1.0/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= -github.com/coredns/corefile-migration v1.0.11 h1:ptBYGW2ADXIB7ZEBPrhhTvNwJLQfxE3Q9IUMBhJCEeI= -github.com/coredns/corefile-migration v1.0.11/go.mod h1:RMy/mXdeDlYwzt0vdMEJvT2hGJ2I86/eO0UdXmH9XNI= github.com/coredns/corefile-migration v1.0.13 h1:ld5RswmH1xjqBUEukw4QxC1PakLNNoVlsZEV8FGwoV8= github.com/coredns/corefile-migration v1.0.13/go.mod h1:XnhgULOEouimnzgn0t4WPuFDN2/PJQcTxdWKC5eXNGE= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -725,7 +714,6 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzz github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= github.com/gobuffalo/flect v0.2.3 h1:f/ZukRnSNA/DUpSNDadko7Qc0PhGvsew35p/2tu+CRY= github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= -github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= @@ -935,7 +923,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -1064,7 +1051,6 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= -github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= @@ -1135,7 +1121,6 @@ github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1173,7 +1158,6 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1183,7 +1167,6 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= @@ -1201,7 +1184,6 @@ github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= @@ -1489,8 +1471,6 @@ github.com/vmware-tanzu/carvel-vendir v0.22.0/go.mod h1:vCzgI/0AqEYKkYN2kexIB1jy github.com/vmware-tanzu/carvel-vendir v0.23.0 h1:7tn0D14nxpYQS4SPRqOGp0ePKAgikYw786YtqmRWJas= github.com/vmware-tanzu/carvel-vendir v0.23.0/go.mod h1:l35I00eXhYiIaZdOPeGX/zrj0WGfimSSqj81PrxGpAw= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/vmware/govmomi v0.26.1/go.mod h1:daTuJEcQosNMXYJOeku0qdBJP9SOLLWB3Mqz8THtv6o= -github.com/vmware/govmomi v0.27.1 h1:Rf3o1btFrkJa9be5KtgJ4CyOO8mbFnBxmNtAVHNyFes= github.com/vmware/govmomi v0.27.1/go.mod h1:daTuJEcQosNMXYJOeku0qdBJP9SOLLWB3Mqz8THtv6o= github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= @@ -1549,73 +1529,46 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/contrib v0.13.0/go.mod h1:HzCu6ebm0ywgNxGaEfs3izyJOMP4rZnzxycyTgpI5Sg= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib v0.22.0/go.mod h1:EH4yDYeNoaTqn/8yCWQmfNB78VHfGX2Jt2bvnvzBlGM= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.13.0/go.mod h1:SeQm4RTCcZ2/hlMSTuHb7nwIROe5odBtgfKx+7MMqEs= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.22.0/go.mod h1:o3MuU25bYroYnc2TOKe8mTk8f9X1oPFO6C5RCoPKtSU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.25.0/go.mod h1:NyB05cd+yPX6W5SiRNuJ90w7PV2+g2cgRbsPL7MvpME= -go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= -go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM= go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU= -go.opentelemetry.io/otel/exporters/metric/prometheus v0.13.0/go.mod h1:Tyh3ACxU9a1tu1mF4at7xvNu+BaiPThrr5XZmsoIW7g= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC2/go.mod h1:T+s8GKi1OqMwPuZ+ouDtZW4vWYpJuzIzh2Matq4Jo9k= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC2/go.mod h1:3shayJIFcDqHi9/GT2fAHyMI/bRgc6FO0CAkhaDkhi0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= -go.opentelemetry.io/otel/exporters/prometheus v0.22.0/go.mod h1:fnolxp61wIq3NvflpkKH7asSqU/tpXPcTZiPhL1+JzE= go.opentelemetry.io/otel/exporters/prometheus v0.24.0/go.mod h1:jfc9W1hVK0w9zrsE+C2ELje/M+K67cGinzeg8qQ8oog= -go.opentelemetry.io/otel/exporters/trace/jaeger v0.13.0/go.mod h1:RSg6E40NYGqN/aCrStCUue2e+jABeFk2bKdNucw63ao= -go.opentelemetry.io/otel/internal/metric v0.22.0/go.mod h1:7qVuMihW/ktMonEfOvBXuh6tfMvvEyoIDgeJNRloYbQ= go.opentelemetry.io/otel/internal/metric v0.24.0/go.mod h1:PSkQG+KuApZjBpC6ea6082ZrWUUy/w132tJ/LOU3TXk= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/metric v0.22.0/go.mod h1:KcsUkBiYGW003DJ+ugd2aqIRIfjabD9jeOUXqsAtrq0= go.opentelemetry.io/otel/metric v0.24.0/go.mod h1:tpMFnCD9t+BEGiWY2bWF5+AwjuAdM0lSowQ4SBA3/K4= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= -go.opentelemetry.io/otel/oteltest v1.0.0-RC2/go.mod h1:kiQ4tw5tAL4JLTbcOYwK1CWI1HkT5aiLzHovgOVnz/A= -go.opentelemetry.io/otel/sdk v0.13.0/go.mod h1:dKvLH8Uu8LcEPlSAUsfW7kMGaJBhk/1NYvpPZ6wIMbU= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= -go.opentelemetry.io/otel/sdk v1.0.0-RC2/go.mod h1:fgwHyiDn4e5k40TD9VX243rOxXR+jzsWBZYA2P5jpEw= go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/export/metric v0.22.0/go.mod h1:a14rf2CiHSn9xjB6cHuv0HoZGl5C4w2PAgl+Lja1VzU= go.opentelemetry.io/otel/sdk/export/metric v0.24.0/go.mod h1:chmxXGVNcpCih5XyniVkL4VUyaEroUbOdvjVlQ8M29Y= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/sdk/metric v0.22.0/go.mod h1:LzkI0G0z6KhEagqmzgk3bw/dglE2Tk2OXs455UMcI0s= go.opentelemetry.io/otel/sdk/metric v0.24.0/go.mod h1:KDgJgYzsIowuIDbPM9sLDZY9JJ6gqIDWCx92iWV8ejk= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= -go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4= go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= @@ -1656,7 +1609,6 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1694,7 +1646,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1757,7 +1708,6 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= @@ -1945,7 +1895,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2276,8 +2225,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= @@ -2300,18 +2247,15 @@ k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI= k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= -k8s.io/api v0.19.6/go.mod h1:Plxx44Nh4zVblkJrIgxVPgPre1mvng6tXf1Sj3bs0fU= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY= k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKizADfvUM/SS/M= k8s.io/apiextensions-apiserver v0.19.2/go.mod h1:EYNjpqIAvNZe+svXVx9j4uBaVhTB4C94HkY3w058qcg= -k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA= k8s.io/apiextensions-apiserver v0.22.2 h1:zK7qI8Ery7j2CaN23UCFaC1hj7dMiI87n01+nKuewd4= k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA= k8s.io/apimachinery v0.16.8/go.mod h1:Xk2vD2TRRpuWYLQNM6lT9R7DSFZUYG03SarNkbGrnKE= @@ -2320,16 +2264,13 @@ k8s.io/apimachinery v0.17.4/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0 k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= -k8s.io/apimachinery v0.19.6/go.mod h1:6sRbGRAVY5DOCuZwB5XkqguBqpqLU6q/kOaOdk29z6Q= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= -k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk= k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= k8s.io/apimachinery v0.22.3 h1:mrvBG5CZnEfwgpVqWcrRKvdsYECTrhAR6cApAgdsflk= k8s.io/apimachinery v0.22.3/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= @@ -2343,21 +2284,17 @@ k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.21.2/go.mod h1:lN4yBoGyiNT7SC1dmNk0ue6a5Wi6O3SWOIw91TsucQw= k8s.io/apiserver v0.22.2 h1:TdIfZJc6YNhu2WxeAOWq1TvukHF0Sfx0+ln4XK9qnL4= k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI= -k8s.io/cli-runtime v0.21.2/go.mod h1:8u/jFcM0QpoI28f6sfrAAIslLCXUYKD5SsPPMWiHYrI= k8s.io/cli-runtime v0.22.2/go.mod h1:tkm2YeORFpbgQHEK/igqttvPTRIHFRz5kATlw53zlMI= k8s.io/client-go v0.16.8/go.mod h1:WmPuN0yJTKHXoklExKxzo3jSXmr3EnN+65uaTb5VuNs= k8s.io/client-go v0.17.4/go.mod h1:ouF6o5pz3is8qU0/qYL2RnoxOPqgfuidYLowytyLJmc= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.18.6/go.mod h1:/fwtGLjYMS1MaM5oi+eXhKwG+1UHidUEXRh6cNsdO0Q= k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA= -k8s.io/client-go v0.19.6/go.mod h1:gEiS+efRlXYUEQ9Oz4lmNXlxAl5JZ8y2zbTDGhvXXnk= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA= k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk= k8s.io/client-go v0.22.2 h1:DaSQgs02aCC1QcwUdkKZWOeaVsQjYvWv8ZazcZ6JcHc= k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U= @@ -2370,25 +2307,21 @@ k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRV k8s.io/code-generator v0.18.6/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/code-generator v0.19.2/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= -k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U= k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= k8s.io/component-base v0.16.8/go.mod h1:Q8UWOWShpP3MZZny4n/15gOncfaaVtc9SbCdkM5MhUE= k8s.io/component-base v0.17.4/go.mod h1:5BRqHMbbQPm2kKu35v3G+CpVq4K0RJKC7TRioF0I9lE= k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/component-base v0.18.6/go.mod h1:knSVsibPR5K6EW2XOjEHik6sdU5nCvKMrzMt2D4In14= k8s.io/component-base v0.19.2/go.mod h1:g5LrsiTiabMLZ40AR6Hl45f088DevyGY+cCE2agEIVo= -k8s.io/component-base v0.19.6/go.mod h1:8Btsf8J00/fVDa/YFmXjei7gVkcFrlKZXjSeP4SZNJg= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc= k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo= k8s.io/component-base v0.22.2 h1:vNIvE0AIrLhjX8drH0BgCNJcR4QZxMXcJzBsDplDx9M= k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug= -k8s.io/component-helpers v0.21.2/go.mod h1:DbyFt/A0p6Cv+R5+QOGSJ5f5t4xDfI8Yb89a57DgJlQ= k8s.io/component-helpers v0.22.2/go.mod h1:+N61JAR9aKYSWbnLA88YcFr9K/6ISYvRNybX7QW7Rs8= k8s.io/cri-api v0.0.0-20191107035106-03d130a7dc28/go.mod h1:9a7E6pmKLfuq8ZL31k2PDpgvSdyZfUOH9czlEmpblFk= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= @@ -2411,9 +2344,6 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.10.0 h1:R2HDMDJsHVTHA2n4RjwbeYXdOcBymXdX/JRb1v0VGhE= @@ -2425,19 +2355,14 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20210929172449-94abcedd1aa4 h1:9GQ7xPpVr9vdAKKCslflyylc7qGdtGtfOQu2r+W4fAk= k8s.io/kube-openapi v0.0.0-20210929172449-94abcedd1aa4/go.mod h1:gULf0pSS32YtLlO7+li/EV8/0y5mG/sO32H4OUsHIQg= -k8s.io/kubectl v0.17.14/go.mod h1:odRYqp1ZCsHThLHdLwK82jvZA3mvbGS75fsztgZd9X0= -k8s.io/kubectl v0.21.2/go.mod h1:PgeUclpG8VVmmQIl8zpLar3IQEpFc9mrmvlwY3CK1xo= k8s.io/kubectl v0.22.2/go.mod h1:BApg2j0edxLArCOfO0ievI27EeTQqBDMNU9VQH734iQ= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js= -k8s.io/metrics v0.21.2/go.mod h1:wzlOINZMCtWq8dR9gHlyaOemmYlOpAoldEIXE82gAhI= k8s.io/metrics v0.22.2/go.mod h1:GUcsBtpsqQD1tKFS/2wCKu4ZBowwRncLOJH1rgWs3uw= k8s.io/sample-controller v0.16.8/go.mod h1:aXlORS1ekU77qhGybB5t3JORDurzDpWgvMYxmCsiuos= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= @@ -2447,7 +2372,6 @@ k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20200912215256-4140de9c8800/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -2470,34 +2394,24 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/aws-iam-authenticator v0.5.3/go.mod h1:DIq7gy0lvnyaG88AgFyJzUVeix+ia5msHEp4RL0102I= sigs.k8s.io/cluster-api v1.0.0 h1:GcVA2ObQTXo/+jzSLWPy4Bd3NeiwJyAB8n19kyJIotA= sigs.k8s.io/cluster-api v1.0.0/go.mod h1:V230kMSaYENTUcx1QRkoRCklb3vfphQGV3/z4ODNGWo= sigs.k8s.io/cluster-api-provider-aws v1.0.0/go.mod h1:obm08FFz9fanAEgLfv5Bl6imtHpilEWgsQCFfuAyoAY= -sigs.k8s.io/cluster-api-provider-azure v0.5.2/go.mod h1:A2D//L/vGLIytrqxYS6WxVlv3cNlql07HW/YlQoqtvU= -sigs.k8s.io/cluster-api-provider-azure v1.0.0-rc.0/go.mod h1:fxvWxmTw58eQtFN5FKx9YrDsYotBkCoJyf48jsl5RUQ= sigs.k8s.io/cluster-api-provider-azure v1.0.0/go.mod h1:fxvWxmTw58eQtFN5FKx9YrDsYotBkCoJyf48jsl5RUQ= -sigs.k8s.io/cluster-api-provider-vsphere v1.0.0/go.mod h1:NV9zOnaZr1tOoKDjW/z7WDioAUVwxfrg3egi0j6M+C0= sigs.k8s.io/cluster-api-provider-vsphere v1.0.1/go.mod h1:Z6MDQcZjX5DUcEFStotBptj2fMR4vgCVPAnw6inIY20= -sigs.k8s.io/cluster-api/test v0.4.0/go.mod h1:Smn0J1FPtwLmd4ipXLb42RSXhKW+ur46qHWXoOAfpgw= sigs.k8s.io/cluster-api/test v1.0.0/go.mod h1:8WQozDv62x2qHkCB1wTUeFjuwawuHKUTh8IMH5hePQs= sigs.k8s.io/controller-runtime v0.6.3/go.mod h1:WlZNXcM0++oyaQt4B7C2lEE5JYRs8vJUzRP4N4JpdAY= sigs.k8s.io/controller-runtime v0.7.0/go.mod h1:pJ3YBrJiAqMAZKi6UVGuE98ZrroV1p+pIhoHsMm9wdU= -sigs.k8s.io/controller-runtime v0.9.1/go.mod h1:cTqsgnwSOsYS03XwySYZj8k6vf0+eC4FJRcCgQ9elb4= sigs.k8s.io/controller-runtime v0.10.2 h1:jW8qiY+yMnnPx6O9hu63tgcwaKzd1yLYui+mpvClOOc= sigs.k8s.io/controller-runtime v0.10.2/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY= sigs.k8s.io/controller-tools v0.4.1/go.mod h1:G9rHdZMVlBDocIxGkK3jHLWqcTMNvveypYJwrvYKjWU= sigs.k8s.io/controller-tools v0.7.0/go.mod h1:bpBAo0VcSDDLuWt47evLhMLPxRPxMDInTEH/YbdeMK0= sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= -sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY= sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g= -sigs.k8s.io/kustomize/cmd/config v0.9.10/go.mod h1:Mrby0WnRH7hA6OwOYnYpfpiY0WJIMgYrEDfwOeFdMK0= sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs= -sigs.k8s.io/kustomize/kustomize/v4 v4.1.2/go.mod h1:PxBvo4WGYlCLeRPL+ziT64wBXqbgfcalOS/SXa/tcyo= sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go= -sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= @@ -2507,7 +2421,6 @@ sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnM sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/cmd/cli/plugin/managementcluster/permissions_aws_generate.go b/cmd/cli/plugin/managementcluster/permissions_aws_generate.go new file mode 100644 index 0000000000..a338f02181 --- /dev/null +++ b/cmd/cli/plugin/managementcluster/permissions_aws_generate.go @@ -0,0 +1,36 @@ +// Copyright 2021 VMware, Inc. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var generateAWSCloudFormationTemplateCmd = &cobra.Command{ + Use: "generate-cloudformation-template", + Short: "Generate AWS CloudFormation Template", + Long: `Generate AWS CloudFormation Template`, + RunE: generateCloudFormationTemplate, +} + +func init() { + generateAWSCloudFormationTemplateCmd.Flags().StringVarP(&setAWSPermissionsOps.clusterConfigFile, "file", "f", "", "Optional, configuration file from which to read the aws credentials. Falls back to using the default AWS credentials chain if not provided.") + awsPermissionsCmd.AddCommand(generateAWSCloudFormationTemplateCmd) +} + +func generateCloudFormationTemplate(cmd *cobra.Command, args []string) error { + forceUpdateTKGCompatibilityImage := false + tkgctlClient, err := newTKGCtlClient(forceUpdateTKGCompatibilityImage) + if err != nil { + return err + } + template, err := tkgctlClient.GenerateAWSCloudFormationTemplate(setAWSPermissionsOps.clusterConfigFile) + if err != nil { + return err + } + fmt.Println(template) + return nil +} diff --git a/cmd/cli/plugin/managementcluster/permissions_aws_set.go b/cmd/cli/plugin/managementcluster/permissions_aws_set.go index 3dbcc26c3e..1ffe7c4f4a 100644 --- a/cmd/cli/plugin/managementcluster/permissions_aws_set.go +++ b/cmd/cli/plugin/managementcluster/permissions_aws_set.go @@ -14,11 +14,11 @@ var setAWSPermissionsCmd = &cobra.Command{ RunE: setAWSPermissions, } -type setAWSPermissionsOptions struct { +type awsPermissionsOptions struct { clusterConfigFile string } -var setAWSPermissionsOps setAWSPermissionsOptions +var setAWSPermissionsOps awsPermissionsOptions func init() { setAWSPermissionsCmd.Flags().StringVarP(&setAWSPermissionsOps.clusterConfigFile, "file", "f", "", "Optional, configuration file from which to read the aws credentials. Falls back to using the default AWS credentials chain if not provided.") diff --git a/go.mod b/go.mod index 5fd57b5935..b8e03766f6 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/aunum/log v0.0.0-20200821225356-38d2e2c8b489 github.com/avinetworks/sdk v0.0.0-20201123134013-c157ef55b6f7 github.com/aws/aws-sdk-go v1.40.56 + github.com/awslabs/goformation/v4 v4.19.5 github.com/briandowns/spinner v1.16.0 github.com/cppforlife/go-cli-ui v0.0.0-20200716203538-1e47f820817f github.com/dgrijalva/jwt-go v3.2.0+incompatible @@ -70,6 +71,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/xid v1.2.1 github.com/satori/go.uuid v1.2.0 + github.com/sergi/go-diff v1.2.0 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/spf13/afero v1.6.0 github.com/spf13/cobra v1.2.1 diff --git a/pkg/v1/providers/config_default.yaml b/pkg/v1/providers/config_default.yaml index 98048828df..36c538cff3 100644 --- a/pkg/v1/providers/config_default.yaml +++ b/pkg/v1/providers/config_default.yaml @@ -414,6 +414,9 @@ TKG_PROXY_CA_CERT: "" #! IP Family setting TKG_IP_FAMILY: +#! Configure cloud provider permissions for TMC enablement. Only affects AWS at present. +ENABLE_TMC_CLOUD_PROVIDER_PERMISSIONS: false + #! Node Nameservers (currently only supports the vSphere provider) CONTROL_PLANE_NODE_NAMESERVERS: WORKER_NODE_NAMESERVERS: diff --git a/pkg/v1/tkg/aws/client.go b/pkg/v1/tkg/aws/client.go index 7fd18bf528..3f640fe151 100644 --- a/pkg/v1/tkg/aws/client.go +++ b/pkg/v1/tkg/aws/client.go @@ -15,7 +15,9 @@ import ( utilpointer "k8s.io/utils/pointer" "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/cloudformation/bootstrap" cloudformation "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/cloudformation/service" + "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/configreader" awscreds "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/credentials" + iamv1 "sigs.k8s.io/cluster-api-provider-aws/iam/api/v1beta1" "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/web/server/models" ) @@ -23,6 +25,7 @@ import ( const ( defaultControlPlaneMinMemoryInGB = 8 defaultControlPlaneMinCPU = 2 + tanzuMissionControlPoliciesSID = "tmccloudvmwarecom" ) type client struct { @@ -250,18 +253,80 @@ func (c *client) ListSubnets(vpcID string) ([]*models.AWSSubnet, error) { } func (c *client) CreateCloudFormationStack() error { - template := bootstrap.NewTemplate() - setDefaultCloudFormationTemplateValue(&template) - cfnSvc := cloudformation.NewService(cfn.New(c.session)) - err := cfnSvc.ReconcileBootstrapStack(template.Spec.StackName, *template.RenderCloudFormation()) + template, err := c.GenerateBootstrapTemplate(GenerateBootstrapTemplateInput{}) if err != nil { return err } + return c.CreateCloudFormationStackWithTemplate(template) +} +func (c *client) CreateCloudFormationStackWithTemplate(template *bootstrap.Template) error { + cfnSvc := cloudformation.NewService(cfn.New(c.session)) + if err := cfnSvc.ReconcileBootstrapStack(template.Spec.StackName, *template.RenderCloudFormation()); err != nil { + return err + } return cfnSvc.ShowStackResources(template.Spec.StackName) } -func setDefaultCloudFormationTemplateValue(t *bootstrap.Template) { +// GenerateBootstrapTemplateInput is the input to the GenerateBootstrapTemplate func +type GenerateBootstrapTemplateInput struct { + // BootstrapConfigFile is the path to a CAPA bootstrapv1 configuration file that can be used + // to customize IAM policies + BootstrapConfigFile string + // EnableTanzuMissionControlPermissions if true will add IAM permissions for use by Tanzu Mission Control + // to all nodes + EnableTanzuMissionControlPermissions bool +} + +// GenerateBootstrapTemplate generates a wrapped CAPA bootstrapv1 configuration specification that controls +// the generation of CloudFormation stacks +func (c *client) GenerateBootstrapTemplate(i GenerateBootstrapTemplateInput) (*bootstrap.Template, error) { + template := bootstrap.NewTemplate() + if i.BootstrapConfigFile != "" { + spec, err := configreader.LoadConfigFile(i.BootstrapConfigFile) + if err != nil { + return nil, err + } + template.Spec = &spec.Spec + } + setDefaultsBootstrapTemplate(&template) + if i.EnableTanzuMissionControlPermissions { + ensureTanzuMissionControlPermissions(&template) + } + return &template, nil +} + +func ensureTanzuMissionControlPermissions(t *bootstrap.Template) { + t.Spec.Nodes.ExtraStatements = ensureTanzuMissionControlPermissionsForRole(t.Spec.Nodes.ExtraStatements) + t.Spec.ControlPlane.ExtraStatements = ensureTanzuMissionControlPermissionsForRole(t.Spec.ControlPlane.ExtraStatements) +} + +func ensureTanzuMissionControlPermissionsForRole(statements []iamv1.StatementEntry) []iamv1.StatementEntry { + tmcStatementEntry := iamv1.StatementEntry{ + Sid: tanzuMissionControlPoliciesSID, + Effect: iamv1.EffectAllow, + Action: iamv1.Actions{ + "ec2:DescribeKeyPairs", + "elasticloadbalancing:DescribeLoadBalancers", + "servicequotas:ListServiceQuotas", + "iam:GetPolicy", + "iam:ListAttachedRolePoliices", + "iam:GetPolicyVersion", + "iam:ListRoleTags", + }, + Resource: iamv1.Resources{iamv1.Any}, + } + for i, statementEntry := range statements { + if statementEntry.Sid == tanzuMissionControlPoliciesSID { + statements[i] = tmcStatementEntry + return statements + } + } + statements = append(statements, tmcStatementEntry) + return statements +} + +func setDefaultsBootstrapTemplate(t *bootstrap.Template) { t.Spec.NameSuffix = utilpointer.StringPtr(DefaultCloudFormationNameSuffix) t.Spec.StackName = DefaultCloudFormationStackName t.Spec.BootstrapUser.UserName = DefaultCloudFormationBootstrapUserName diff --git a/pkg/v1/tkg/aws/client_test.go b/pkg/v1/tkg/aws/client_test.go index 233701167c..cc8f18a9b4 100644 --- a/pkg/v1/tkg/aws/client_test.go +++ b/pkg/v1/tkg/aws/client_test.go @@ -4,11 +4,18 @@ package aws_test import ( + "fmt" + "os" + "path" "testing" + "github.com/awslabs/goformation/v4/cloudformation" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/sergi/go-diff/diffmatchpatch" + "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/cloudformation/bootstrap" awscreds "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/credentials" + "sigs.k8s.io/yaml" "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/aws" ) @@ -36,15 +43,17 @@ var _ = Describe("Unit tests for aws client", func() { awsClient aws.Client ) + JustBeforeEach(func() { + awsCreds := awscreds.AWSCredentials{ + AccessKeyID: accessKeyID, + SecretAccessKey: secretAccessKey, + Region: region, + } + awsClient, err = aws.New(awsCreds) + }) Describe("Encode aws credentials", func() { var encodedCreds string JustBeforeEach(func() { - awsCreds := awscreds.AWSCredentials{ - AccessKeyID: accessKeyID, - SecretAccessKey: secretAccessKey, - Region: region, - } - awsClient, err = aws.New(awsCreds) Expect(err).ToNot(HaveOccurred()) encodedCreds, err = awsClient.EncodeCredentials() }) @@ -73,4 +82,42 @@ var _ = Describe("Unit tests for aws client", func() { }) }) }) + + Describe("Generating Cloudformation", func() { + awsClient, err = aws.New(awscreds.AWSCredentials{ + AccessKeyID: fakeRegion, + SecretAccessKey: fakeAccessKeyID, + Region: fakeSecretAccessKey, + }) + Expect(err).ToNot(HaveOccurred()) + }) + Context("Defaults", func() { + template, err := awsClient.GenerateBootstrapTemplate(aws.GenerateBootstrapTemplateInput{}) + Expect(err).NotTo(HaveOccurred()) + testBootstrapTemplate("default", template) + }) + Context("With TMC Permissions", func() { + template, err := awsClient.GenerateBootstrapTemplate(aws.GenerateBootstrapTemplateInput{ + EnableTanzuMissionControlPermissions: true, + }) + Expect(err).NotTo(HaveOccurred()) + testBootstrapTemplate("with-tmc", template) + }) }) + +func testBootstrapTemplate(name string, template *bootstrap.Template) { + defer GinkgoRecover() + cfn := cloudformation.Template{} + data, err := os.ReadFile(path.Join("fixtures", "cloudformation-"+name+".yaml")) + Expect(err).ToNot(HaveOccurred()) + err = yaml.Unmarshal(data, cfn) + Expect(err).ToNot(HaveOccurred()) + tData, err := template.RenderCloudFormation().YAML() + Expect(err).ToNot(HaveOccurred()) + err = os.WriteFile("/tmp/tmp1", tData, 0600) + Expect(err).ToNot(HaveOccurred()) + dmp := diffmatchpatch.New() + diffs := dmp.DiffMain(string(tData), string(data), false) + out := dmp.DiffPrettyText(diffs) + Expect(string(tData)).To(Equal(string(data)), fmt.Sprintf("Differing output (%s):\n%s", name, out)) +} diff --git a/pkg/v1/tkg/aws/fixtures/cloudformation-default.yaml b/pkg/v1/tkg/aws/fixtures/cloudformation-default.yaml new file mode 100644 index 0000000000..a03914bd19 --- /dev/null +++ b/pkg/v1/tkg/aws/fixtures/cloudformation-default.yaml @@ -0,0 +1,295 @@ +AWSTemplateFormatVersion: 2010-09-09 +Resources: + AWSIAMInstanceProfileControlPlane: + Properties: + InstanceProfileName: control-plane.tkg.cloud.vmware.com + Roles: + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::InstanceProfile + AWSIAMInstanceProfileControllers: + Properties: + InstanceProfileName: controllers.tkg.cloud.vmware.com + Roles: + - Ref: AWSIAMRoleControllers + Type: AWS::IAM::InstanceProfile + AWSIAMInstanceProfileNodes: + Properties: + InstanceProfileName: nodes.tkg.cloud.vmware.com + Roles: + - Ref: AWSIAMRoleNodes + Type: AWS::IAM::InstanceProfile + AWSIAMManagedPolicyCloudProviderControlPlane: + Properties: + Description: For the Kubernetes Cloud Provider AWS Control Plane + ManagedPolicyName: control-plane.tkg.cloud.vmware.com + PolicyDocument: + Statement: + - Action: + - autoscaling:DescribeAutoScalingGroups + - autoscaling:DescribeLaunchConfigurations + - autoscaling:DescribeTags + - ec2:DescribeInstances + - ec2:DescribeImages + - ec2:DescribeRegions + - ec2:DescribeRouteTables + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVolumes + - ec2:CreateSecurityGroup + - ec2:CreateTags + - ec2:CreateVolume + - ec2:ModifyInstanceAttribute + - ec2:ModifyVolume + - ec2:AttachVolume + - ec2:AuthorizeSecurityGroupIngress + - ec2:CreateRoute + - ec2:DeleteRoute + - ec2:DeleteSecurityGroup + - ec2:DeleteVolume + - ec2:DetachVolume + - ec2:RevokeSecurityGroupIngress + - ec2:DescribeVpcs + - elasticloadbalancing:AddTags + - elasticloadbalancing:AttachLoadBalancerToSubnets + - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer + - elasticloadbalancing:CreateLoadBalancer + - elasticloadbalancing:CreateLoadBalancerPolicy + - elasticloadbalancing:CreateLoadBalancerListeners + - elasticloadbalancing:ConfigureHealthCheck + - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:DeleteLoadBalancerListeners + - elasticloadbalancing:DescribeLoadBalancers + - elasticloadbalancing:DescribeLoadBalancerAttributes + - elasticloadbalancing:DetachLoadBalancerFromSubnets + - elasticloadbalancing:DeregisterInstancesFromLoadBalancer + - elasticloadbalancing:ModifyLoadBalancerAttributes + - elasticloadbalancing:RegisterInstancesWithLoadBalancer + - elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer + - elasticloadbalancing:CreateListener + - elasticloadbalancing:CreateTargetGroup + - elasticloadbalancing:DeleteListener + - elasticloadbalancing:DeleteTargetGroup + - elasticloadbalancing:DescribeListeners + - elasticloadbalancing:DescribeLoadBalancerPolicies + - elasticloadbalancing:DescribeTargetGroups + - elasticloadbalancing:DescribeTargetHealth + - elasticloadbalancing:ModifyListener + - elasticloadbalancing:ModifyTargetGroup + - elasticloadbalancing:RegisterTargets + - elasticloadbalancing:SetLoadBalancerPoliciesOfListener + - iam:CreateServiceLinkedRole + - kms:DescribeKey + Effect: Allow + Resource: + - '*' + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::ManagedPolicy + AWSIAMManagedPolicyCloudProviderNodes: + Properties: + Description: For the Kubernetes Cloud Provider AWS nodes + ManagedPolicyName: nodes.tkg.cloud.vmware.com + PolicyDocument: + Statement: + - Action: + - ec2:DescribeInstances + - ec2:DescribeRegions + - ecr:GetAuthorizationToken + - ecr:BatchCheckLayerAvailability + - ecr:GetDownloadUrlForLayer + - ecr:GetRepositoryPolicy + - ecr:DescribeRepositories + - ecr:ListImages + - ecr:BatchGetImage + Effect: Allow + Resource: + - '*' + - Action: + - secretsmanager:DeleteSecret + - secretsmanager:GetSecretValue + Effect: Allow + Resource: + - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/* + - Action: + - ssm:UpdateInstanceInformation + - ssmmessages:CreateControlChannel + - ssmmessages:CreateDataChannel + - ssmmessages:OpenControlChannel + - ssmmessages:OpenDataChannel + - s3:GetEncryptionConfiguration + Effect: Allow + Resource: + - '*' + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControlPlane + - Ref: AWSIAMRoleNodes + Type: AWS::IAM::ManagedPolicy + AWSIAMManagedPolicyControllers: + Properties: + Description: For the Kubernetes Cluster API Provider AWS Controllers + ManagedPolicyName: controllers.tkg.cloud.vmware.com + PolicyDocument: + Statement: + - Action: + - ec2:AllocateAddress + - ec2:AssociateRouteTable + - ec2:AttachInternetGateway + - ec2:AuthorizeSecurityGroupIngress + - ec2:CreateInternetGateway + - ec2:CreateNatGateway + - ec2:CreateRoute + - ec2:CreateRouteTable + - ec2:CreateSecurityGroup + - ec2:CreateSubnet + - ec2:CreateTags + - ec2:CreateVpc + - ec2:ModifyVpcAttribute + - ec2:DeleteInternetGateway + - ec2:DeleteNatGateway + - ec2:DeleteRouteTable + - ec2:DeleteSecurityGroup + - ec2:DeleteSubnet + - ec2:DeleteTags + - ec2:DeleteVpc + - ec2:DescribeAccountAttributes + - ec2:DescribeAddresses + - ec2:DescribeAvailabilityZones + - ec2:DescribeInstances + - ec2:DescribeInternetGateways + - ec2:DescribeImages + - ec2:DescribeNatGateways + - ec2:DescribeNetworkInterfaces + - ec2:DescribeNetworkInterfaceAttribute + - ec2:DescribeRouteTables + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVpcs + - ec2:DescribeVpcAttribute + - ec2:DescribeVolumes + - ec2:DetachInternetGateway + - ec2:DisassociateRouteTable + - ec2:DisassociateAddress + - ec2:ModifyInstanceAttribute + - ec2:ModifyNetworkInterfaceAttribute + - ec2:ModifySubnetAttribute + - ec2:ReleaseAddress + - ec2:RevokeSecurityGroupIngress + - ec2:RunInstances + - ec2:TerminateInstances + - tag:GetResources + - elasticloadbalancing:AddTags + - elasticloadbalancing:CreateLoadBalancer + - elasticloadbalancing:ConfigureHealthCheck + - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:DescribeLoadBalancers + - elasticloadbalancing:DescribeLoadBalancerAttributes + - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer + - elasticloadbalancing:DescribeTags + - elasticloadbalancing:ModifyLoadBalancerAttributes + - elasticloadbalancing:RegisterInstancesWithLoadBalancer + - elasticloadbalancing:DeregisterInstancesFromLoadBalancer + - elasticloadbalancing:RemoveTags + - autoscaling:DescribeAutoScalingGroups + - autoscaling:DescribeInstanceRefreshes + - ec2:CreateLaunchTemplate + - ec2:CreateLaunchTemplateVersion + - ec2:DescribeLaunchTemplates + - ec2:DescribeLaunchTemplateVersions + - ec2:DeleteLaunchTemplate + - ec2:DeleteLaunchTemplateVersions + - ec2:DescribeKeyPairs + Effect: Allow + Resource: + - '*' + - Action: + - autoscaling:CreateAutoScalingGroup + - autoscaling:UpdateAutoScalingGroup + - autoscaling:CreateOrUpdateTags + - autoscaling:StartInstanceRefresh + - autoscaling:DeleteAutoScalingGroup + - autoscaling:DeleteTags + Effect: Allow + Resource: + - arn:*:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/* + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: autoscaling.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: elasticloadbalancing.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: spot.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot + - Action: + - iam:PassRole + Effect: Allow + Resource: + - arn:*:iam::*:role/*.tkg.cloud.vmware.com + - Action: + - secretsmanager:CreateSecret + - secretsmanager:DeleteSecret + - secretsmanager:TagResource + Effect: Allow + Resource: + - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/* + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControllers + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::ManagedPolicy + AWSIAMRoleControlPlane: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + RoleName: control-plane.tkg.cloud.vmware.com + Type: AWS::IAM::Role + AWSIAMRoleControllers: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + RoleName: controllers.tkg.cloud.vmware.com + Type: AWS::IAM::Role + AWSIAMRoleNodes: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + RoleName: nodes.tkg.cloud.vmware.com + Type: AWS::IAM::Role diff --git a/pkg/v1/tkg/aws/fixtures/cloudformation-with-tmc.yaml b/pkg/v1/tkg/aws/fixtures/cloudformation-with-tmc.yaml new file mode 100644 index 0000000000..c2702d9e27 --- /dev/null +++ b/pkg/v1/tkg/aws/fixtures/cloudformation-with-tmc.yaml @@ -0,0 +1,329 @@ +AWSTemplateFormatVersion: 2010-09-09 +Resources: + AWSIAMInstanceProfileControlPlane: + Properties: + InstanceProfileName: control-plane.tkg.cloud.vmware.com + Roles: + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::InstanceProfile + AWSIAMInstanceProfileControllers: + Properties: + InstanceProfileName: controllers.tkg.cloud.vmware.com + Roles: + - Ref: AWSIAMRoleControllers + Type: AWS::IAM::InstanceProfile + AWSIAMInstanceProfileNodes: + Properties: + InstanceProfileName: nodes.tkg.cloud.vmware.com + Roles: + - Ref: AWSIAMRoleNodes + Type: AWS::IAM::InstanceProfile + AWSIAMManagedPolicyCloudProviderControlPlane: + Properties: + Description: For the Kubernetes Cloud Provider AWS Control Plane + ManagedPolicyName: control-plane.tkg.cloud.vmware.com + PolicyDocument: + Statement: + - Action: + - autoscaling:DescribeAutoScalingGroups + - autoscaling:DescribeLaunchConfigurations + - autoscaling:DescribeTags + - ec2:DescribeInstances + - ec2:DescribeImages + - ec2:DescribeRegions + - ec2:DescribeRouteTables + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVolumes + - ec2:CreateSecurityGroup + - ec2:CreateTags + - ec2:CreateVolume + - ec2:ModifyInstanceAttribute + - ec2:ModifyVolume + - ec2:AttachVolume + - ec2:AuthorizeSecurityGroupIngress + - ec2:CreateRoute + - ec2:DeleteRoute + - ec2:DeleteSecurityGroup + - ec2:DeleteVolume + - ec2:DetachVolume + - ec2:RevokeSecurityGroupIngress + - ec2:DescribeVpcs + - elasticloadbalancing:AddTags + - elasticloadbalancing:AttachLoadBalancerToSubnets + - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer + - elasticloadbalancing:CreateLoadBalancer + - elasticloadbalancing:CreateLoadBalancerPolicy + - elasticloadbalancing:CreateLoadBalancerListeners + - elasticloadbalancing:ConfigureHealthCheck + - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:DeleteLoadBalancerListeners + - elasticloadbalancing:DescribeLoadBalancers + - elasticloadbalancing:DescribeLoadBalancerAttributes + - elasticloadbalancing:DetachLoadBalancerFromSubnets + - elasticloadbalancing:DeregisterInstancesFromLoadBalancer + - elasticloadbalancing:ModifyLoadBalancerAttributes + - elasticloadbalancing:RegisterInstancesWithLoadBalancer + - elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer + - elasticloadbalancing:CreateListener + - elasticloadbalancing:CreateTargetGroup + - elasticloadbalancing:DeleteListener + - elasticloadbalancing:DeleteTargetGroup + - elasticloadbalancing:DescribeListeners + - elasticloadbalancing:DescribeLoadBalancerPolicies + - elasticloadbalancing:DescribeTargetGroups + - elasticloadbalancing:DescribeTargetHealth + - elasticloadbalancing:ModifyListener + - elasticloadbalancing:ModifyTargetGroup + - elasticloadbalancing:RegisterTargets + - elasticloadbalancing:SetLoadBalancerPoliciesOfListener + - iam:CreateServiceLinkedRole + - kms:DescribeKey + Effect: Allow + Resource: + - '*' + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::ManagedPolicy + AWSIAMManagedPolicyCloudProviderNodes: + Properties: + Description: For the Kubernetes Cloud Provider AWS nodes + ManagedPolicyName: nodes.tkg.cloud.vmware.com + PolicyDocument: + Statement: + - Action: + - ec2:DescribeInstances + - ec2:DescribeRegions + - ecr:GetAuthorizationToken + - ecr:BatchCheckLayerAvailability + - ecr:GetDownloadUrlForLayer + - ecr:GetRepositoryPolicy + - ecr:DescribeRepositories + - ecr:ListImages + - ecr:BatchGetImage + Effect: Allow + Resource: + - '*' + - Action: + - secretsmanager:DeleteSecret + - secretsmanager:GetSecretValue + Effect: Allow + Resource: + - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/* + - Action: + - ssm:UpdateInstanceInformation + - ssmmessages:CreateControlChannel + - ssmmessages:CreateDataChannel + - ssmmessages:OpenControlChannel + - ssmmessages:OpenDataChannel + - s3:GetEncryptionConfiguration + Effect: Allow + Resource: + - '*' + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControlPlane + - Ref: AWSIAMRoleNodes + Type: AWS::IAM::ManagedPolicy + AWSIAMManagedPolicyControllers: + Properties: + Description: For the Kubernetes Cluster API Provider AWS Controllers + ManagedPolicyName: controllers.tkg.cloud.vmware.com + PolicyDocument: + Statement: + - Action: + - ec2:AllocateAddress + - ec2:AssociateRouteTable + - ec2:AttachInternetGateway + - ec2:AuthorizeSecurityGroupIngress + - ec2:CreateInternetGateway + - ec2:CreateNatGateway + - ec2:CreateRoute + - ec2:CreateRouteTable + - ec2:CreateSecurityGroup + - ec2:CreateSubnet + - ec2:CreateTags + - ec2:CreateVpc + - ec2:ModifyVpcAttribute + - ec2:DeleteInternetGateway + - ec2:DeleteNatGateway + - ec2:DeleteRouteTable + - ec2:DeleteSecurityGroup + - ec2:DeleteSubnet + - ec2:DeleteTags + - ec2:DeleteVpc + - ec2:DescribeAccountAttributes + - ec2:DescribeAddresses + - ec2:DescribeAvailabilityZones + - ec2:DescribeInstances + - ec2:DescribeInternetGateways + - ec2:DescribeImages + - ec2:DescribeNatGateways + - ec2:DescribeNetworkInterfaces + - ec2:DescribeNetworkInterfaceAttribute + - ec2:DescribeRouteTables + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVpcs + - ec2:DescribeVpcAttribute + - ec2:DescribeVolumes + - ec2:DetachInternetGateway + - ec2:DisassociateRouteTable + - ec2:DisassociateAddress + - ec2:ModifyInstanceAttribute + - ec2:ModifyNetworkInterfaceAttribute + - ec2:ModifySubnetAttribute + - ec2:ReleaseAddress + - ec2:RevokeSecurityGroupIngress + - ec2:RunInstances + - ec2:TerminateInstances + - tag:GetResources + - elasticloadbalancing:AddTags + - elasticloadbalancing:CreateLoadBalancer + - elasticloadbalancing:ConfigureHealthCheck + - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:DescribeLoadBalancers + - elasticloadbalancing:DescribeLoadBalancerAttributes + - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer + - elasticloadbalancing:DescribeTags + - elasticloadbalancing:ModifyLoadBalancerAttributes + - elasticloadbalancing:RegisterInstancesWithLoadBalancer + - elasticloadbalancing:DeregisterInstancesFromLoadBalancer + - elasticloadbalancing:RemoveTags + - autoscaling:DescribeAutoScalingGroups + - autoscaling:DescribeInstanceRefreshes + - ec2:CreateLaunchTemplate + - ec2:CreateLaunchTemplateVersion + - ec2:DescribeLaunchTemplates + - ec2:DescribeLaunchTemplateVersions + - ec2:DeleteLaunchTemplate + - ec2:DeleteLaunchTemplateVersions + - ec2:DescribeKeyPairs + Effect: Allow + Resource: + - '*' + - Action: + - autoscaling:CreateAutoScalingGroup + - autoscaling:UpdateAutoScalingGroup + - autoscaling:CreateOrUpdateTags + - autoscaling:StartInstanceRefresh + - autoscaling:DeleteAutoScalingGroup + - autoscaling:DeleteTags + Effect: Allow + Resource: + - arn:*:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/* + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: autoscaling.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: elasticloadbalancing.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing + - Action: + - iam:CreateServiceLinkedRole + Condition: + StringLike: + iam:AWSServiceName: spot.amazonaws.com + Effect: Allow + Resource: + - arn:*:iam::*:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot + - Action: + - iam:PassRole + Effect: Allow + Resource: + - arn:*:iam::*:role/*.tkg.cloud.vmware.com + - Action: + - secretsmanager:CreateSecret + - secretsmanager:DeleteSecret + - secretsmanager:TagResource + Effect: Allow + Resource: + - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/* + Version: 2012-10-17 + Roles: + - Ref: AWSIAMRoleControllers + - Ref: AWSIAMRoleControlPlane + Type: AWS::IAM::ManagedPolicy + AWSIAMRoleControlPlane: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + Policies: + - PolicyDocument: + Statement: + - Action: + - ec2:DescribeKeyPairs + - elasticloadbalancing:DescribeLoadBalancers + - servicequotas:ListServiceQuotas + - iam:GetPolicy + - iam:ListAttachedRolePoliices + - iam:GetPolicyVersion + - iam:ListRoleTags + Effect: Allow + Resource: + - '*' + Sid: tmccloudvmwarecom + Version: 2012-10-17 + PolicyName: tkg-cloud-vmware-com + RoleName: control-plane.tkg.cloud.vmware.com + Type: AWS::IAM::Role + AWSIAMRoleControllers: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + RoleName: controllers.tkg.cloud.vmware.com + Type: AWS::IAM::Role + AWSIAMRoleNodes: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Version: 2012-10-17 + Policies: + - PolicyDocument: + Statement: + - Action: + - ec2:DescribeKeyPairs + - elasticloadbalancing:DescribeLoadBalancers + - servicequotas:ListServiceQuotas + - iam:GetPolicy + - iam:ListAttachedRolePoliices + - iam:GetPolicyVersion + - iam:ListRoleTags + Effect: Allow + Resource: + - '*' + Sid: tmccloudvmwarecom + Version: 2012-10-17 + PolicyName: tkg-cloud-vmware-com + RoleName: nodes.tkg.cloud.vmware.com + Type: AWS::IAM::Role diff --git a/pkg/v1/tkg/aws/interface.go b/pkg/v1/tkg/aws/interface.go index 766e8cfa5e..71c1fd46d5 100644 --- a/pkg/v1/tkg/aws/interface.go +++ b/pkg/v1/tkg/aws/interface.go @@ -5,6 +5,8 @@ package aws import ( + "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/cloudformation/bootstrap" + "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/web/server/models" ) @@ -20,6 +22,8 @@ type Client interface { GetSubnetGatewayAssociations(vpcID string) (map[string]bool, error) ListSubnets(vpcID string) ([]*models.AWSSubnet, error) CreateCloudFormationStack() error + CreateCloudFormationStackWithTemplate(template *bootstrap.Template) error + GenerateBootstrapTemplate(i GenerateBootstrapTemplateInput) (*bootstrap.Template, error) ListInstanceTypes(optionalAZName string) ([]string, error) ListCloudFormationStacks() ([]string, error) } diff --git a/pkg/v1/tkg/client/client.go b/pkg/v1/tkg/client/client.go index c6408c2646..fb7c571eec 100644 --- a/pkg/v1/tkg/client/client.go +++ b/pkg/v1/tkg/client/client.go @@ -126,6 +126,8 @@ type Client interface { GetRegionContexts(clusterName string) ([]region.RegionContext, error) // SetRegionContext sets a management cluster context to be current context SetRegionContext(clusterName string, contextName string) error + // GenerateAWSCloudFormationTemplate generates a CloudFormation YAML template + GenerateAWSCloudFormationTemplate() (string, error) // GetCurrentRegionContext() gets the current management cluster context GetCurrentRegionContext() (region.RegionContext, error) // GetWorkloadClusterCredentials merges workload cluster credentials into kubeconfig path diff --git a/pkg/v1/tkg/client/config_permission.go b/pkg/v1/tkg/client/config_permission.go index d5486dec3e..585b89400d 100644 --- a/pkg/v1/tkg/client/config_permission.go +++ b/pkg/v1/tkg/client/config_permission.go @@ -5,6 +5,7 @@ package client import ( "os" + "strings" "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/aws" "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/constants" @@ -12,6 +13,7 @@ import ( "github.com/pkg/errors" + "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/cloudformation/bootstrap" "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/credentials" ) @@ -21,6 +23,12 @@ const awsCredentialError = "failed to gather credentials for operation that requ func (c *TkgClient) CreateAWSCloudFormationStack() error { log.SendProgressUpdate(statusRunning, StepConfigPrerequisite, InitRegionSteps) log.Info("Creating AWS CloudFormation Stack") + template, err := c.generateAWSBootstrapTemplate() + + if err != nil { + return errors.Wrap(err, "failed to generate template") + } + creds, err := c.GetAWSCreds() if err != nil { return errors.Wrap(err, "unable to retrieve AWS credentials") @@ -31,13 +39,50 @@ func (c *TkgClient) CreateAWSCloudFormationStack() error { return errors.Wrap(err, "failed create AWS client") } - err = awsClient.CreateCloudFormationStack() + err = awsClient.CreateCloudFormationStackWithTemplate(template) if err != nil { return errors.Wrap(err, "failed to create aws CloudFormation stack") } return nil } +// GenerateAWSCloudFormationTemplate produces the CloudFormation template YAML +func (c *TkgClient) GenerateAWSCloudFormationTemplate() (string, error) { + template, err := c.generateAWSBootstrapTemplate() + if err != nil { + return "", err + } + cfnTemplate := template.RenderCloudFormation() + dat, err := cfnTemplate.YAML() + if err != nil { + return "", err + } + return string(dat), nil +} + +func (c *TkgClient) generateAWSBootstrapTemplate() (*bootstrap.Template, error) { + // Don't need a full client + awsClient, err := aws.New(credentials.AWSCredentials{}) + if err != nil { + return nil, errors.Wrap(err, "failed create AWS client") + } + + tmcEnablement := false + + tmcEnablementVar, err := c.TKGConfigReaderWriter().Get(constants.ConfigVariableEnableTMCCloudProviderPermissions) + if err == nil && strings.EqualFold(tmcEnablementVar, "true") { + tmcEnablement = true + } + + template, err := awsClient.GenerateBootstrapTemplate(aws.GenerateBootstrapTemplateInput{ + EnableTanzuMissionControlPermissions: tmcEnablement, + }) + if err != nil { + return nil, err + } + return template, nil +} + // GetAWSCreds get aws credentials func (c *TkgClient) GetAWSCreds() (*credentials.AWSCredentials, error) { region, err := c.getAWSRegion() diff --git a/pkg/v1/tkg/constants/config_variables.go b/pkg/v1/tkg/constants/config_variables.go index 28e0ccd6eb..c01b488c1b 100644 --- a/pkg/v1/tkg/constants/config_variables.go +++ b/pkg/v1/tkg/constants/config_variables.go @@ -102,14 +102,15 @@ const ( ConfigVariablePinnipedSupervisorIssuerURL = "SUPERVISOR_ISSUER_URL" ConfigVariablePinnipedSupervisorIssuerCABundleData = "SUPERVISOR_ISSUER_CA_BUNDLE_DATA_B64" - ConfigVariableClusterRole = "TKG_CLUSTER_ROLE" - ConfigVariableForceRole = "_TKG_CLUSTER_FORCE_ROLE" - ConfigVariableProviderType = "PROVIDER_TYPE" - ConfigVariableTKGVersion = "TKG_VERSION" - ConfigVariableBuildEdition = "BUILD_EDITION" - ConfigVariableFilterByAddonType = "FILTER_BY_ADDON_TYPE" - ConfigVaraibleDisableCRSForAddonType = "DISABLE_CRS_FOR_ADDON_TYPE" - ConfigVariableEnableAutoscaler = "ENABLE_AUTOSCALER" + ConfigVariableClusterRole = "TKG_CLUSTER_ROLE" + ConfigVariableForceRole = "_TKG_CLUSTER_FORCE_ROLE" + ConfigVariableProviderType = "PROVIDER_TYPE" + ConfigVariableTKGVersion = "TKG_VERSION" + ConfigVariableBuildEdition = "BUILD_EDITION" + ConfigVariableFilterByAddonType = "FILTER_BY_ADDON_TYPE" + ConfigVaraibleDisableCRSForAddonType = "DISABLE_CRS_FOR_ADDON_TYPE" + ConfigVariableEnableAutoscaler = "ENABLE_AUTOSCALER" + ConfigVariableEnableTMCCloudProviderPermissions = "ENABLE_TMC_CLOUD_PROVIDER_PERMISSIONS" ConfigVariableControlPlaneMachineCount = "CONTROL_PLANE_MACHINE_COUNT" ConfigVariableWorkerMachineCount = "WORKER_MACHINE_COUNT" diff --git a/pkg/v1/tkg/fakes/awsclient.go b/pkg/v1/tkg/fakes/awsclient.go index d6287ee14a..0f3a89d58f 100644 --- a/pkg/v1/tkg/fakes/awsclient.go +++ b/pkg/v1/tkg/fakes/awsclient.go @@ -4,6 +4,8 @@ package fakes import ( "sync" + "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/cloudformation/bootstrap" + "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/aws" "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/web/server/models" ) @@ -19,6 +21,17 @@ type AWSClient struct { createCloudFormationStackReturnsOnCall map[int]struct { result1 error } + CreateCloudFormationStackWithTemplateStub func(*bootstrap.Template) error + createCloudFormationStackWithTemplateMutex sync.RWMutex + createCloudFormationStackWithTemplateArgsForCall []struct { + arg1 *bootstrap.Template + } + createCloudFormationStackWithTemplateReturns struct { + result1 error + } + createCloudFormationStackWithTemplateReturnsOnCall map[int]struct { + result1 error + } EncodeCredentialsStub func() (string, error) encodeCredentialsMutex sync.RWMutex encodeCredentialsArgsForCall []struct { @@ -31,6 +44,19 @@ type AWSClient struct { result1 string result2 error } + GenerateBootstrapTemplateStub func(aws.GenerateBootstrapTemplateInput) (*bootstrap.Template, error) + generateBootstrapTemplateMutex sync.RWMutex + generateBootstrapTemplateArgsForCall []struct { + arg1 aws.GenerateBootstrapTemplateInput + } + generateBootstrapTemplateReturns struct { + result1 *bootstrap.Template + result2 error + } + generateBootstrapTemplateReturnsOnCall map[int]struct { + result1 *bootstrap.Template + result2 error + } GetSubnetGatewayAssociationsStub func(string) (map[string]bool, error) getSubnetGatewayAssociationsMutex sync.RWMutex getSubnetGatewayAssociationsArgsForCall []struct { @@ -185,6 +211,67 @@ func (fake *AWSClient) CreateCloudFormationStackReturnsOnCall(i int, result1 err }{result1} } +func (fake *AWSClient) CreateCloudFormationStackWithTemplate(arg1 *bootstrap.Template) error { + fake.createCloudFormationStackWithTemplateMutex.Lock() + ret, specificReturn := fake.createCloudFormationStackWithTemplateReturnsOnCall[len(fake.createCloudFormationStackWithTemplateArgsForCall)] + fake.createCloudFormationStackWithTemplateArgsForCall = append(fake.createCloudFormationStackWithTemplateArgsForCall, struct { + arg1 *bootstrap.Template + }{arg1}) + stub := fake.CreateCloudFormationStackWithTemplateStub + fakeReturns := fake.createCloudFormationStackWithTemplateReturns + fake.recordInvocation("CreateCloudFormationStackWithTemplate", []interface{}{arg1}) + fake.createCloudFormationStackWithTemplateMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *AWSClient) CreateCloudFormationStackWithTemplateCallCount() int { + fake.createCloudFormationStackWithTemplateMutex.RLock() + defer fake.createCloudFormationStackWithTemplateMutex.RUnlock() + return len(fake.createCloudFormationStackWithTemplateArgsForCall) +} + +func (fake *AWSClient) CreateCloudFormationStackWithTemplateCalls(stub func(*bootstrap.Template) error) { + fake.createCloudFormationStackWithTemplateMutex.Lock() + defer fake.createCloudFormationStackWithTemplateMutex.Unlock() + fake.CreateCloudFormationStackWithTemplateStub = stub +} + +func (fake *AWSClient) CreateCloudFormationStackWithTemplateArgsForCall(i int) *bootstrap.Template { + fake.createCloudFormationStackWithTemplateMutex.RLock() + defer fake.createCloudFormationStackWithTemplateMutex.RUnlock() + argsForCall := fake.createCloudFormationStackWithTemplateArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *AWSClient) CreateCloudFormationStackWithTemplateReturns(result1 error) { + fake.createCloudFormationStackWithTemplateMutex.Lock() + defer fake.createCloudFormationStackWithTemplateMutex.Unlock() + fake.CreateCloudFormationStackWithTemplateStub = nil + fake.createCloudFormationStackWithTemplateReturns = struct { + result1 error + }{result1} +} + +func (fake *AWSClient) CreateCloudFormationStackWithTemplateReturnsOnCall(i int, result1 error) { + fake.createCloudFormationStackWithTemplateMutex.Lock() + defer fake.createCloudFormationStackWithTemplateMutex.Unlock() + fake.CreateCloudFormationStackWithTemplateStub = nil + if fake.createCloudFormationStackWithTemplateReturnsOnCall == nil { + fake.createCloudFormationStackWithTemplateReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.createCloudFormationStackWithTemplateReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *AWSClient) EncodeCredentials() (string, error) { fake.encodeCredentialsMutex.Lock() ret, specificReturn := fake.encodeCredentialsReturnsOnCall[len(fake.encodeCredentialsArgsForCall)] @@ -241,6 +328,70 @@ func (fake *AWSClient) EncodeCredentialsReturnsOnCall(i int, result1 string, res }{result1, result2} } +func (fake *AWSClient) GenerateBootstrapTemplate(arg1 aws.GenerateBootstrapTemplateInput) (*bootstrap.Template, error) { + fake.generateBootstrapTemplateMutex.Lock() + ret, specificReturn := fake.generateBootstrapTemplateReturnsOnCall[len(fake.generateBootstrapTemplateArgsForCall)] + fake.generateBootstrapTemplateArgsForCall = append(fake.generateBootstrapTemplateArgsForCall, struct { + arg1 aws.GenerateBootstrapTemplateInput + }{arg1}) + stub := fake.GenerateBootstrapTemplateStub + fakeReturns := fake.generateBootstrapTemplateReturns + fake.recordInvocation("GenerateBootstrapTemplate", []interface{}{arg1}) + fake.generateBootstrapTemplateMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *AWSClient) GenerateBootstrapTemplateCallCount() int { + fake.generateBootstrapTemplateMutex.RLock() + defer fake.generateBootstrapTemplateMutex.RUnlock() + return len(fake.generateBootstrapTemplateArgsForCall) +} + +func (fake *AWSClient) GenerateBootstrapTemplateCalls(stub func(aws.GenerateBootstrapTemplateInput) (*bootstrap.Template, error)) { + fake.generateBootstrapTemplateMutex.Lock() + defer fake.generateBootstrapTemplateMutex.Unlock() + fake.GenerateBootstrapTemplateStub = stub +} + +func (fake *AWSClient) GenerateBootstrapTemplateArgsForCall(i int) aws.GenerateBootstrapTemplateInput { + fake.generateBootstrapTemplateMutex.RLock() + defer fake.generateBootstrapTemplateMutex.RUnlock() + argsForCall := fake.generateBootstrapTemplateArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *AWSClient) GenerateBootstrapTemplateReturns(result1 *bootstrap.Template, result2 error) { + fake.generateBootstrapTemplateMutex.Lock() + defer fake.generateBootstrapTemplateMutex.Unlock() + fake.GenerateBootstrapTemplateStub = nil + fake.generateBootstrapTemplateReturns = struct { + result1 *bootstrap.Template + result2 error + }{result1, result2} +} + +func (fake *AWSClient) GenerateBootstrapTemplateReturnsOnCall(i int, result1 *bootstrap.Template, result2 error) { + fake.generateBootstrapTemplateMutex.Lock() + defer fake.generateBootstrapTemplateMutex.Unlock() + fake.GenerateBootstrapTemplateStub = nil + if fake.generateBootstrapTemplateReturnsOnCall == nil { + fake.generateBootstrapTemplateReturnsOnCall = make(map[int]struct { + result1 *bootstrap.Template + result2 error + }) + } + fake.generateBootstrapTemplateReturnsOnCall[i] = struct { + result1 *bootstrap.Template + result2 error + }{result1, result2} +} + func (fake *AWSClient) GetSubnetGatewayAssociations(arg1 string) (map[string]bool, error) { fake.getSubnetGatewayAssociationsMutex.Lock() ret, specificReturn := fake.getSubnetGatewayAssociationsReturnsOnCall[len(fake.getSubnetGatewayAssociationsArgsForCall)] @@ -715,8 +866,12 @@ func (fake *AWSClient) Invocations() map[string][][]interface{} { defer fake.invocationsMutex.RUnlock() fake.createCloudFormationStackMutex.RLock() defer fake.createCloudFormationStackMutex.RUnlock() + fake.createCloudFormationStackWithTemplateMutex.RLock() + defer fake.createCloudFormationStackWithTemplateMutex.RUnlock() fake.encodeCredentialsMutex.RLock() defer fake.encodeCredentialsMutex.RUnlock() + fake.generateBootstrapTemplateMutex.RLock() + defer fake.generateBootstrapTemplateMutex.RUnlock() fake.getSubnetGatewayAssociationsMutex.RLock() defer fake.getSubnetGatewayAssociationsMutex.RUnlock() fake.listAvailabilityZonesMutex.RLock() diff --git a/pkg/v1/tkg/fakes/client.go b/pkg/v1/tkg/fakes/client.go index 35a127e87b..831bed06bf 100644 --- a/pkg/v1/tkg/fakes/client.go +++ b/pkg/v1/tkg/fakes/client.go @@ -193,6 +193,18 @@ type Client struct { downloadBomFileReturnsOnCall map[int]struct { result1 error } + GenerateAWSCloudFormationTemplateStub func() (string, error) + generateAWSCloudFormationTemplateMutex sync.RWMutex + generateAWSCloudFormationTemplateArgsForCall []struct { + } + generateAWSCloudFormationTemplateReturns struct { + result1 string + result2 error + } + generateAWSCloudFormationTemplateReturnsOnCall map[int]struct { + result1 string + result2 error + } GetCEIPParticipationStub func() (client.ClusterCeipInfo, error) getCEIPParticipationMutex sync.RWMutex getCEIPParticipationArgsForCall []struct { @@ -1506,6 +1518,62 @@ func (fake *Client) DownloadBomFileReturnsOnCall(i int, result1 error) { }{result1} } +func (fake *Client) GenerateAWSCloudFormationTemplate() (string, error) { + fake.generateAWSCloudFormationTemplateMutex.Lock() + ret, specificReturn := fake.generateAWSCloudFormationTemplateReturnsOnCall[len(fake.generateAWSCloudFormationTemplateArgsForCall)] + fake.generateAWSCloudFormationTemplateArgsForCall = append(fake.generateAWSCloudFormationTemplateArgsForCall, struct { + }{}) + stub := fake.GenerateAWSCloudFormationTemplateStub + fakeReturns := fake.generateAWSCloudFormationTemplateReturns + fake.recordInvocation("GenerateAWSCloudFormationTemplate", []interface{}{}) + fake.generateAWSCloudFormationTemplateMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *Client) GenerateAWSCloudFormationTemplateCallCount() int { + fake.generateAWSCloudFormationTemplateMutex.RLock() + defer fake.generateAWSCloudFormationTemplateMutex.RUnlock() + return len(fake.generateAWSCloudFormationTemplateArgsForCall) +} + +func (fake *Client) GenerateAWSCloudFormationTemplateCalls(stub func() (string, error)) { + fake.generateAWSCloudFormationTemplateMutex.Lock() + defer fake.generateAWSCloudFormationTemplateMutex.Unlock() + fake.GenerateAWSCloudFormationTemplateStub = stub +} + +func (fake *Client) GenerateAWSCloudFormationTemplateReturns(result1 string, result2 error) { + fake.generateAWSCloudFormationTemplateMutex.Lock() + defer fake.generateAWSCloudFormationTemplateMutex.Unlock() + fake.GenerateAWSCloudFormationTemplateStub = nil + fake.generateAWSCloudFormationTemplateReturns = struct { + result1 string + result2 error + }{result1, result2} +} + +func (fake *Client) GenerateAWSCloudFormationTemplateReturnsOnCall(i int, result1 string, result2 error) { + fake.generateAWSCloudFormationTemplateMutex.Lock() + defer fake.generateAWSCloudFormationTemplateMutex.Unlock() + fake.GenerateAWSCloudFormationTemplateStub = nil + if fake.generateAWSCloudFormationTemplateReturnsOnCall == nil { + fake.generateAWSCloudFormationTemplateReturnsOnCall = make(map[int]struct { + result1 string + result2 error + }) + } + fake.generateAWSCloudFormationTemplateReturnsOnCall[i] = struct { + result1 string + result2 error + }{result1, result2} +} + func (fake *Client) GetCEIPParticipation() (client.ClusterCeipInfo, error) { fake.getCEIPParticipationMutex.Lock() ret, specificReturn := fake.getCEIPParticipationReturnsOnCall[len(fake.getCEIPParticipationArgsForCall)] @@ -3654,6 +3722,8 @@ func (fake *Client) Invocations() map[string][][]interface{} { defer fake.describeProviderMutex.RUnlock() fake.downloadBomFileMutex.RLock() defer fake.downloadBomFileMutex.RUnlock() + fake.generateAWSCloudFormationTemplateMutex.RLock() + defer fake.generateAWSCloudFormationTemplateMutex.RUnlock() fake.getCEIPParticipationMutex.RLock() defer fake.getCEIPParticipationMutex.RUnlock() fake.getClusterConfigurationMutex.RLock() diff --git a/pkg/v1/tkg/fakes/featuresclient.go b/pkg/v1/tkg/fakes/featuresclient.go new file mode 100644 index 0000000000..4664fa0b7a --- /dev/null +++ b/pkg/v1/tkg/fakes/featuresclient.go @@ -0,0 +1,339 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package fakes + +import ( + "sync" + + "github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkg/features" +) + +type FeaturesClient struct { + GetFeatureFlagStub func(string) (string, error) + getFeatureFlagMutex sync.RWMutex + getFeatureFlagArgsForCall []struct { + arg1 string + } + getFeatureFlagReturns struct { + result1 string + result2 error + } + getFeatureFlagReturnsOnCall map[int]struct { + result1 string + result2 error + } + GetFeatureFlagsStub func() (map[string]string, error) + getFeatureFlagsMutex sync.RWMutex + getFeatureFlagsArgsForCall []struct { + } + getFeatureFlagsReturns struct { + result1 map[string]string + result2 error + } + getFeatureFlagsReturnsOnCall map[int]struct { + result1 map[string]string + result2 error + } + IsFeatureFlagEnabledStub func(string) (bool, error) + isFeatureFlagEnabledMutex sync.RWMutex + isFeatureFlagEnabledArgsForCall []struct { + arg1 string + } + isFeatureFlagEnabledReturns struct { + result1 bool + result2 error + } + isFeatureFlagEnabledReturnsOnCall map[int]struct { + result1 bool + result2 error + } + WriteFeatureFlagsStub func(map[string]string) error + writeFeatureFlagsMutex sync.RWMutex + writeFeatureFlagsArgsForCall []struct { + arg1 map[string]string + } + writeFeatureFlagsReturns struct { + result1 error + } + writeFeatureFlagsReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FeaturesClient) GetFeatureFlag(arg1 string) (string, error) { + fake.getFeatureFlagMutex.Lock() + ret, specificReturn := fake.getFeatureFlagReturnsOnCall[len(fake.getFeatureFlagArgsForCall)] + fake.getFeatureFlagArgsForCall = append(fake.getFeatureFlagArgsForCall, struct { + arg1 string + }{arg1}) + stub := fake.GetFeatureFlagStub + fakeReturns := fake.getFeatureFlagReturns + fake.recordInvocation("GetFeatureFlag", []interface{}{arg1}) + fake.getFeatureFlagMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FeaturesClient) GetFeatureFlagCallCount() int { + fake.getFeatureFlagMutex.RLock() + defer fake.getFeatureFlagMutex.RUnlock() + return len(fake.getFeatureFlagArgsForCall) +} + +func (fake *FeaturesClient) GetFeatureFlagCalls(stub func(string) (string, error)) { + fake.getFeatureFlagMutex.Lock() + defer fake.getFeatureFlagMutex.Unlock() + fake.GetFeatureFlagStub = stub +} + +func (fake *FeaturesClient) GetFeatureFlagArgsForCall(i int) string { + fake.getFeatureFlagMutex.RLock() + defer fake.getFeatureFlagMutex.RUnlock() + argsForCall := fake.getFeatureFlagArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FeaturesClient) GetFeatureFlagReturns(result1 string, result2 error) { + fake.getFeatureFlagMutex.Lock() + defer fake.getFeatureFlagMutex.Unlock() + fake.GetFeatureFlagStub = nil + fake.getFeatureFlagReturns = struct { + result1 string + result2 error + }{result1, result2} +} + +func (fake *FeaturesClient) GetFeatureFlagReturnsOnCall(i int, result1 string, result2 error) { + fake.getFeatureFlagMutex.Lock() + defer fake.getFeatureFlagMutex.Unlock() + fake.GetFeatureFlagStub = nil + if fake.getFeatureFlagReturnsOnCall == nil { + fake.getFeatureFlagReturnsOnCall = make(map[int]struct { + result1 string + result2 error + }) + } + fake.getFeatureFlagReturnsOnCall[i] = struct { + result1 string + result2 error + }{result1, result2} +} + +func (fake *FeaturesClient) GetFeatureFlags() (map[string]string, error) { + fake.getFeatureFlagsMutex.Lock() + ret, specificReturn := fake.getFeatureFlagsReturnsOnCall[len(fake.getFeatureFlagsArgsForCall)] + fake.getFeatureFlagsArgsForCall = append(fake.getFeatureFlagsArgsForCall, struct { + }{}) + stub := fake.GetFeatureFlagsStub + fakeReturns := fake.getFeatureFlagsReturns + fake.recordInvocation("GetFeatureFlags", []interface{}{}) + fake.getFeatureFlagsMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FeaturesClient) GetFeatureFlagsCallCount() int { + fake.getFeatureFlagsMutex.RLock() + defer fake.getFeatureFlagsMutex.RUnlock() + return len(fake.getFeatureFlagsArgsForCall) +} + +func (fake *FeaturesClient) GetFeatureFlagsCalls(stub func() (map[string]string, error)) { + fake.getFeatureFlagsMutex.Lock() + defer fake.getFeatureFlagsMutex.Unlock() + fake.GetFeatureFlagsStub = stub +} + +func (fake *FeaturesClient) GetFeatureFlagsReturns(result1 map[string]string, result2 error) { + fake.getFeatureFlagsMutex.Lock() + defer fake.getFeatureFlagsMutex.Unlock() + fake.GetFeatureFlagsStub = nil + fake.getFeatureFlagsReturns = struct { + result1 map[string]string + result2 error + }{result1, result2} +} + +func (fake *FeaturesClient) GetFeatureFlagsReturnsOnCall(i int, result1 map[string]string, result2 error) { + fake.getFeatureFlagsMutex.Lock() + defer fake.getFeatureFlagsMutex.Unlock() + fake.GetFeatureFlagsStub = nil + if fake.getFeatureFlagsReturnsOnCall == nil { + fake.getFeatureFlagsReturnsOnCall = make(map[int]struct { + result1 map[string]string + result2 error + }) + } + fake.getFeatureFlagsReturnsOnCall[i] = struct { + result1 map[string]string + result2 error + }{result1, result2} +} + +func (fake *FeaturesClient) IsFeatureFlagEnabled(arg1 string) (bool, error) { + fake.isFeatureFlagEnabledMutex.Lock() + ret, specificReturn := fake.isFeatureFlagEnabledReturnsOnCall[len(fake.isFeatureFlagEnabledArgsForCall)] + fake.isFeatureFlagEnabledArgsForCall = append(fake.isFeatureFlagEnabledArgsForCall, struct { + arg1 string + }{arg1}) + stub := fake.IsFeatureFlagEnabledStub + fakeReturns := fake.isFeatureFlagEnabledReturns + fake.recordInvocation("IsFeatureFlagEnabled", []interface{}{arg1}) + fake.isFeatureFlagEnabledMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FeaturesClient) IsFeatureFlagEnabledCallCount() int { + fake.isFeatureFlagEnabledMutex.RLock() + defer fake.isFeatureFlagEnabledMutex.RUnlock() + return len(fake.isFeatureFlagEnabledArgsForCall) +} + +func (fake *FeaturesClient) IsFeatureFlagEnabledCalls(stub func(string) (bool, error)) { + fake.isFeatureFlagEnabledMutex.Lock() + defer fake.isFeatureFlagEnabledMutex.Unlock() + fake.IsFeatureFlagEnabledStub = stub +} + +func (fake *FeaturesClient) IsFeatureFlagEnabledArgsForCall(i int) string { + fake.isFeatureFlagEnabledMutex.RLock() + defer fake.isFeatureFlagEnabledMutex.RUnlock() + argsForCall := fake.isFeatureFlagEnabledArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FeaturesClient) IsFeatureFlagEnabledReturns(result1 bool, result2 error) { + fake.isFeatureFlagEnabledMutex.Lock() + defer fake.isFeatureFlagEnabledMutex.Unlock() + fake.IsFeatureFlagEnabledStub = nil + fake.isFeatureFlagEnabledReturns = struct { + result1 bool + result2 error + }{result1, result2} +} + +func (fake *FeaturesClient) IsFeatureFlagEnabledReturnsOnCall(i int, result1 bool, result2 error) { + fake.isFeatureFlagEnabledMutex.Lock() + defer fake.isFeatureFlagEnabledMutex.Unlock() + fake.IsFeatureFlagEnabledStub = nil + if fake.isFeatureFlagEnabledReturnsOnCall == nil { + fake.isFeatureFlagEnabledReturnsOnCall = make(map[int]struct { + result1 bool + result2 error + }) + } + fake.isFeatureFlagEnabledReturnsOnCall[i] = struct { + result1 bool + result2 error + }{result1, result2} +} + +func (fake *FeaturesClient) WriteFeatureFlags(arg1 map[string]string) error { + fake.writeFeatureFlagsMutex.Lock() + ret, specificReturn := fake.writeFeatureFlagsReturnsOnCall[len(fake.writeFeatureFlagsArgsForCall)] + fake.writeFeatureFlagsArgsForCall = append(fake.writeFeatureFlagsArgsForCall, struct { + arg1 map[string]string + }{arg1}) + stub := fake.WriteFeatureFlagsStub + fakeReturns := fake.writeFeatureFlagsReturns + fake.recordInvocation("WriteFeatureFlags", []interface{}{arg1}) + fake.writeFeatureFlagsMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FeaturesClient) WriteFeatureFlagsCallCount() int { + fake.writeFeatureFlagsMutex.RLock() + defer fake.writeFeatureFlagsMutex.RUnlock() + return len(fake.writeFeatureFlagsArgsForCall) +} + +func (fake *FeaturesClient) WriteFeatureFlagsCalls(stub func(map[string]string) error) { + fake.writeFeatureFlagsMutex.Lock() + defer fake.writeFeatureFlagsMutex.Unlock() + fake.WriteFeatureFlagsStub = stub +} + +func (fake *FeaturesClient) WriteFeatureFlagsArgsForCall(i int) map[string]string { + fake.writeFeatureFlagsMutex.RLock() + defer fake.writeFeatureFlagsMutex.RUnlock() + argsForCall := fake.writeFeatureFlagsArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FeaturesClient) WriteFeatureFlagsReturns(result1 error) { + fake.writeFeatureFlagsMutex.Lock() + defer fake.writeFeatureFlagsMutex.Unlock() + fake.WriteFeatureFlagsStub = nil + fake.writeFeatureFlagsReturns = struct { + result1 error + }{result1} +} + +func (fake *FeaturesClient) WriteFeatureFlagsReturnsOnCall(i int, result1 error) { + fake.writeFeatureFlagsMutex.Lock() + defer fake.writeFeatureFlagsMutex.Unlock() + fake.WriteFeatureFlagsStub = nil + if fake.writeFeatureFlagsReturnsOnCall == nil { + fake.writeFeatureFlagsReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.writeFeatureFlagsReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *FeaturesClient) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.getFeatureFlagMutex.RLock() + defer fake.getFeatureFlagMutex.RUnlock() + fake.getFeatureFlagsMutex.RLock() + defer fake.getFeatureFlagsMutex.RUnlock() + fake.isFeatureFlagEnabledMutex.RLock() + defer fake.isFeatureFlagEnabledMutex.RUnlock() + fake.writeFeatureFlagsMutex.RLock() + defer fake.writeFeatureFlagsMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FeaturesClient) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ features.Client = new(FeaturesClient) diff --git a/pkg/v1/tkg/tkgctl/config_permission_aws.go b/pkg/v1/tkg/tkgctl/config_permission_aws.go index 3ab3679acc..5128296325 100644 --- a/pkg/v1/tkg/tkgctl/config_permission_aws.go +++ b/pkg/v1/tkg/tkgctl/config_permission_aws.go @@ -5,11 +5,16 @@ package tkgctl // CreateAWSCloudFormationStack create aws cloud formation stack func (t *tkgctl) CreateAWSCloudFormationStack(clusterConfigFile string) error { - var err error - _, err = t.ensureClusterConfigFile(clusterConfigFile) - if err != nil { + if _, err := t.ensureClusterConfigFile(clusterConfigFile); err != nil { return err } - return t.tkgClient.CreateAWSCloudFormationStack() } + +// CreateAWSCloudFormationStack create aws cloud formation stack +func (t *tkgctl) GenerateAWSCloudFormationTemplate(clusterConfigFile string) (string, error) { + if _, err := t.ensureClusterConfigFile(clusterConfigFile); err != nil { + return "", err + } + return t.tkgClient.GenerateAWSCloudFormationTemplate() +} diff --git a/pkg/v1/tkg/tkgctl/interface.go b/pkg/v1/tkg/tkgctl/interface.go index ceeaa07065..8871005cf7 100644 --- a/pkg/v1/tkg/tkgctl/interface.go +++ b/pkg/v1/tkg/tkgctl/interface.go @@ -38,6 +38,8 @@ type TKGClient interface { DescribeCluster(options DescribeTKGClustersOptions) (DescribeClusterResult, error) // DescribeProviders describes all the installed providers DescribeProviders() (*clusterctlv1.ProviderList, error) + // GenerateAWSCloudFormationTemplate generates a YAML template for AWS CloudFormation + GenerateAWSCloudFormationTemplate(clusterConfigFile string) (string, error) // GetCredentials saves cluster credentials to a file GetCredentials(options GetWorkloadClusterCredentialsOptions) error // GetKubernetesVersions returns supported k8s versions