From 9f4318579d54120c9a405afefec67c044757f6b0 Mon Sep 17 00:00:00 2001 From: Vignesh Goutham Ganesh Date: Thu, 16 Jan 2025 15:47:20 -0600 Subject: [PATCH] Rocky support for nodeadm + tests --- cmd/nodeadm/install/install.go | 3 + go.mod | 23 +++- go.sum | 42 +++++- hack/SKIPPED_TESTS.yaml | 2 + hack/run-e2e.sh | 2 +- internal/containerd/install.go | 4 +- internal/creds/creds.go | 14 +- internal/system/os.go | 7 + .../{roelsanywhere.go => rolesanywhere.go} | 0 test/e2e/kubernetes/kubernetes.go | 2 +- test/e2e/os/ami.go | 65 +++++++++ test/e2e/os/rhel.go | 63 +-------- test/e2e/os/rocky.go | 124 ++++++++++++++++++ test/e2e/os/testdata/nodeadm-init.sh | 2 +- test/e2e/os/testdata/rhel/8/cloud-init.txt | 2 + test/e2e/os/testdata/rhel/9/cloud-init.txt | 2 + test/e2e/suite/nodeadm_test.go | 6 +- 17 files changed, 287 insertions(+), 76 deletions(-) rename test/e2e/credentials/{roelsanywhere.go => rolesanywhere.go} (100%) create mode 100644 test/e2e/os/ami.go create mode 100644 test/e2e/os/rocky.go diff --git a/cmd/nodeadm/install/install.go b/cmd/nodeadm/install/install.go index 1ad6fd5a..fa573a49 100644 --- a/cmd/nodeadm/install/install.go +++ b/cmd/nodeadm/install/install.go @@ -82,6 +82,9 @@ func (c *command) Run(log *zap.Logger, opts *cli.GlobalOptions) error { if err != nil { return err } + if err := creds.ValidateCredentialProvider(credentialProvider); err != nil { + return err + } // Default containerd source to distro if c.containerdSource == "" { diff --git a/go.mod b/go.mod index 7c850abf..ea3d119a 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,11 @@ module github.com/aws/eks-hybrid -go 1.22 +go 1.22.0 + +toolchain go1.23.3 require ( + github.com/aws/aws-cdk-go/awscdk/v2 v2.176.0 github.com/aws/aws-sdk-go v1.55.5 github.com/aws/aws-sdk-go-v2/config v1.26.6 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 @@ -15,6 +18,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 github.com/aws/aws-sdk-go-v2/service/ssm v1.51.1 github.com/aws/aws-sdk-go-v2/service/sts v1.28.4 + github.com/aws/constructs-go/constructs/v10 v10.4.2 + github.com/aws/jsii-runtime-go v1.106.0 github.com/aws/smithy-go v1.22.1 github.com/containerd/containerd v1.7.13 github.com/coreos/go-systemd/v22 v22.5.0 @@ -24,10 +29,10 @@ require ( github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/tredoe/osutil v1.5.0 go.uber.org/zap v1.26.0 - golang.org/x/mod v0.18.0 + golang.org/x/mod v0.22.0 k8s.io/apimachinery v0.29.5 k8s.io/client-go v0.29.5 k8s.io/cri-api v0.29.5 @@ -39,18 +44,26 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect + github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect + github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.208 // indirect + github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.3 // indirect + github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.1.0 // indirect + github.com/cdklabs/cloud-assembly-schema-go/awscdkcloudassemblyschema/v39 v39.1.34 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/fatih/color v1.18.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect @@ -59,7 +72,9 @@ require ( github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect + github.com/yuin/goldmark v1.4.13 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect k8s.io/cli-runtime v0.29.5 // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect @@ -122,7 +137,7 @@ require ( golang.org/x/term v0.27.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.28.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect google.golang.org/grpc v1.62.1 // indirect diff --git a/go.sum b/go.sum index ada8eb5a..dddd833d 100644 --- a/go.sum +++ b/go.sum @@ -6,10 +6,14 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aws/aws-cdk-go/awscdk/v2 v2.176.0 h1:cibkzI5ytFV9FoxVBpjUReHd73KBJcfD2515fT8eZJQ= +github.com/aws/aws-cdk-go/awscdk/v2 v2.176.0/go.mod h1:XmbvfJtG3yL0j7qyO/5VmkzR6aVcnMM2esXp0VxKuqY= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= @@ -60,12 +64,24 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.2 h1:pi0Skl6mNl2w8qWZXcdOyg19 github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.2/go.mod h1:JYzLoEVeLXk+L4tn1+rrkfhkxl6mLDEVaDSvGq9og90= github.com/aws/aws-sdk-go-v2/service/sts v1.28.4 h1:Ppup1nVNAOWbBOrcoOxaxPeEnSFB2RnnQdguhXpmeQk= github.com/aws/aws-sdk-go-v2/service/sts v1.28.4/go.mod h1:+K1rNPVyGxkRuv9NNiaZ4YhBFuyw2MMA9SlIJ1Zlpz8= +github.com/aws/constructs-go/constructs/v10 v10.4.2 h1:+hDLTsFGLJmKIn0Dg20vWpKBrVnFrEWYgTEY5UiTEG8= +github.com/aws/constructs-go/constructs/v10 v10.4.2/go.mod h1:cXsNCKDV+9eR9zYYfwy6QuE4uPFp6jsq6TtH1MwBx9w= +github.com/aws/jsii-runtime-go v1.106.0 h1:wClD7enF+FOGR6l2TQ6STcE1nEIVKdODbipl5ZrbyC8= +github.com/aws/jsii-runtime-go v1.106.0/go.mod h1:HMdZwwcI8gpwetrneEa/RUkefS194IeCeh8eJQP3xSk= github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.208 h1:paqCb41y89OFA3+APC7buPjM6Izq8Q0yMgkGSGf/QJI= +github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.208/go.mod h1:zydxApP2CyfXc3jMpJdyb1ERPNVXaCH/LJTKfWfzUBA= +github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.3 h1:u63i5K09xASBNGEM0hpD2z0JwO+iNLVzG74VG85OjDo= +github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.3/go.mod h1:0xP6iiSIKPKsShb6T2kadnTq61wL+kwmHTHnEjkFZFI= +github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.1.0 h1:kElXjprC8wkpJu58vp+WFH6z0AJw4zitg5iSKJPKe3c= +github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.1.0/go.mod h1:JY4UnvNa1YDGQ4H5wohXTHl6YVY3uCDUWl4JYUrQfb8= +github.com/cdklabs/cloud-assembly-schema-go/awscdkcloudassemblyschema/v39 v39.1.34 h1:ObFlfGCEAIUWHZnExynucV/1pegE1mTolBpd3J9kgIk= +github.com/cdklabs/cloud-assembly-schema-go/awscdkcloudassemblyschema/v39 v39.1.34/go.mod h1:9QiFxM66GW99YsAIO06RSB2xge7wUs97jNzMOevksc0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -95,6 +111,8 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= @@ -187,6 +205,11 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -246,14 +269,15 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tredoe/osutil v1.5.0 h1:UGVxbbHRoZi8xXVmbNZ2vgG6XoJ15ndE4LniiQ3rJKg= github.com/tredoe/osutil v1.5.0/go.mod h1:TEzphzUUunysbdDRfdOgqkg10POQbnfIPV50ynqOfIg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= @@ -271,11 +295,14 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -309,6 +336,8 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -330,11 +359,12 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/hack/SKIPPED_TESTS.yaml b/hack/SKIPPED_TESTS.yaml index 8a6bb060..7e48b63b 100644 --- a/hack/SKIPPED_TESTS.yaml +++ b/hack/SKIPPED_TESTS.yaml @@ -6,3 +6,5 @@ skipped_tests: - "ubuntu2004-amd64-docker.*" - "ubuntu2204-amd64-docker.*" - "ubuntu2404-amd64-docker.*" + - "rocky8-amd64.*iam-ra" + - "rocky8-arm64.*iam-ra" diff --git a/hack/run-e2e.sh b/hack/run-e2e.sh index f61d7d54..7ecbfe6d 100755 --- a/hack/run-e2e.sh +++ b/hack/run-e2e.sh @@ -76,7 +76,7 @@ SKIP_FILE=$REPO_ROOT/hack/SKIPPED_TESTS.yaml # Extract skipped_tests field from SKIP_FILE file and join entries with ' || ' skip=$(yq '.skipped_tests | join("|")' ${SKIP_FILE}) -# We expliclty specify procs instead of letting ginkgo decide (with -p) because in if not +# We explicitly specify procs instead of letting ginkgo decide (with -p) because in if not # ginkgo will use all available CPUs, which could be a small number depending # on how the CI runner has been configured. However, even if only one CPU is avaialble, # there is still value in running the tests in multiple processes, since most of the work is diff --git a/internal/containerd/install.go b/internal/containerd/install.go index 3dc355ac..ab175059 100644 --- a/internal/containerd/install.go +++ b/internal/containerd/install.go @@ -71,8 +71,8 @@ func ValidateContainerdSource(source SourceName) error { return fmt.Errorf("docker source for containerd is not supported on AL2023. Please provide `none` or `distro` to the --containerd-source flag") } } else if source == ContainerdSourceDistro { - if osName == system.RhelOsName { - return fmt.Errorf("distro source for containerd is not supported on RHEL. Please provide `none` or `docker` to the --containerd-source flag") + if osName == system.RhelOsName || osName == system.RockyOsName { + return fmt.Errorf("distro source for containerd is not supported on %s based operating systems. Please provide `none` or `docker` to the --containerd-source flag", osName) } } return nil diff --git a/internal/creds/creds.go b/internal/creds/creds.go index 3766c456..5570946b 100644 --- a/internal/creds/creds.go +++ b/internal/creds/creds.go @@ -2,9 +2,10 @@ package creds import ( "fmt" - "github.com/aws/eks-hybrid/internal/api" + "github.com/aws/eks-hybrid/internal/system" "github.com/aws/eks-hybrid/internal/tracker" + "golang.org/x/mod/semver" ) type CredentialProvider string @@ -42,3 +43,14 @@ func GetCredentialProviderFromInstalledArtifacts(artifacts *tracker.InstalledArt } return "", fmt.Errorf("no credential process found in installed artifacts") } + +func ValidateCredentialProvider(provider CredentialProvider) error { + osName, osVersion := system.GetOsNameWithVersion() + majorOsVersion := semver.Major("v" + osVersion) + + if (osName == system.RhelOsName || osName == system.RockyOsName) && majorOsVersion == "v8" && + provider == IamRolesAnywhereCredentialProvider { + return fmt.Errorf("iam-ra credential provider is not supported on %s %s based operating systems. Please use ssm credential provider", osName, osVersion) + } + return nil +} diff --git a/internal/system/os.go b/internal/system/os.go index f9ba9670..a30caaf9 100644 --- a/internal/system/os.go +++ b/internal/system/os.go @@ -5,6 +5,7 @@ import "github.com/go-ini/ini" const ( UbuntuOsName = "ubuntu" RhelOsName = "rhel" + RockyOsName = "rocky" AmazonOsName = "amzn" UbuntuResolvConfPath = "/run/systemd/resolve/resolv.conf" @@ -16,6 +17,12 @@ func GetOsName() string { return cfg.Section("").Key("ID").String() } +// GetOsNameWithVersion returns the os name and version on /etc/os-release file +func GetOsNameWithVersion() (string, string) { + cfg, _ := ini.Load("/etc/os-release") + return cfg.Section("").Key("ID").String(), cfg.Section("").Key("VERSION_ID").String() +} + func GetVersionCodeName() string { cfg, _ := ini.Load("/etc/os-release") return cfg.Section("").Key("VERSION_CODENAME").String() diff --git a/test/e2e/credentials/roelsanywhere.go b/test/e2e/credentials/rolesanywhere.go similarity index 100% rename from test/e2e/credentials/roelsanywhere.go rename to test/e2e/credentials/rolesanywhere.go diff --git a/test/e2e/kubernetes/kubernetes.go b/test/e2e/kubernetes/kubernetes.go index 9027f56a..24ebc5ce 100644 --- a/test/e2e/kubernetes/kubernetes.go +++ b/test/e2e/kubernetes/kubernetes.go @@ -31,7 +31,7 @@ import ( const ( nodePodWaitTimeout = 3 * time.Minute nodePodDelayInterval = 5 * time.Second - hybridNodeWaitTimeout = 10 * time.Minute + hybridNodeWaitTimeout = 12 * time.Minute hybridNodeDelayInterval = 5 * time.Second hybridNodeUpgradeTimeout = 2 * time.Minute nodeCordonDelayInterval = 1 * time.Second diff --git a/test/e2e/os/ami.go b/test/e2e/os/ami.go new file mode 100644 index 00000000..8904b7c7 --- /dev/null +++ b/test/e2e/os/ami.go @@ -0,0 +1,65 @@ +package os + +import ( + "context" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ec2" + "github.com/aws/aws-sdk-go-v2/service/ec2/types" +) + +// AMI represents an ec2 Image. +type AMI struct { + ID string + CreatedAt time.Time +} + +// findLatestImage returns the most recent AMI matching the amiPrefix and arch and owned by ownerAccount +func findLatestImage(ctx context.Context, client *ec2.Client, ownerAccount, amiPrefix, arch string) (string, error) { + var latestAMI AMI + + in := &ec2.DescribeImagesInput{ + Owners: []string{ownerAccount}, + Filters: []types.Filter{{Name: aws.String("name"), Values: []string{amiPrefix}}, {Name: aws.String("architecture"), Values: []string{arch}}}, + MaxResults: aws.Int32(100), + } + + for { + l, err := client.DescribeImages(ctx, in) + if err != nil { + return "", err + } + + if paginationDone(in, l) { + break + } + + for _, i := range l.Images { + created, err := time.Parse(time.RFC3339Nano, *i.CreationDate) + if err != nil { + return "", err + } + if created.Compare(latestAMI.CreatedAt) > 0 { + latestAMI = AMI{ + ID: *i.ImageId, + CreatedAt: created, + } + } + } + + in.NextToken = l.NextToken + + if in.NextToken == nil { + break + } + } + + return latestAMI.ID, nil +} + +func paginationDone(in *ec2.DescribeImagesInput, out *ec2.DescribeImagesOutput) bool { + // Filters work on the returned output per page. Its important we go through all the pages + // and only end pagination when next token == input token + return out.NextToken != nil && in.NextToken == out.NextToken +} diff --git a/test/e2e/os/rhel.go b/test/e2e/os/rhel.go index 533f1326..d715e984 100644 --- a/test/e2e/os/rhel.go +++ b/test/e2e/os/rhel.go @@ -3,13 +3,11 @@ package os import ( "context" _ "embed" - "time" + + "github.com/aws/eks-hybrid/test/e2e" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ec2" - "github.com/aws/aws-sdk-go-v2/service/ec2/types" - - "github.com/aws/eks-hybrid/test/e2e" ) const rhelAWSAccount = "309956199498" @@ -70,7 +68,7 @@ func (r RedHat8) InstanceType(region string) string { func (r RedHat8) AMIName(ctx context.Context, awsConfig aws.Config) (string, error) { // there is no rhel ssm parameter // aws ec2 describe-images --owners 309956199498 --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' --filters "Name=name,Values=RHEL-8*" "Name=architecture,Values=x86_64" --region us-west-2 - return findLatestImage(ctx, ec2.NewFromConfig(awsConfig), "RHEL-8*", r.amiArchitecture) + return findLatestImage(ctx, ec2.NewFromConfig(awsConfig), rhelAWSAccount, "RHEL-8*", r.amiArchitecture) } func (r RedHat8) BuildUserData(userDataInput e2e.UserDataInput) ([]byte, error) { @@ -128,7 +126,7 @@ func (r RedHat9) InstanceType(region string) string { func (r RedHat9) AMIName(ctx context.Context, awsConfig aws.Config) (string, error) { // there is no rhel ssm parameter // aws ec2 describe-images --owners 309956199498 --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' --filters "Name=name,Values=RHEL-9*" "Name=architecture,Values=x86_64" --region us-west-2 - return findLatestImage(ctx, ec2.NewFromConfig(awsConfig), "RHEL-9*", r.amiArchitecture) + return findLatestImage(ctx, ec2.NewFromConfig(awsConfig), rhelAWSAccount, "RHEL-9*", r.amiArchitecture) } func (r RedHat9) BuildUserData(userDataInput e2e.UserDataInput) ([]byte, error) { @@ -151,56 +149,3 @@ func (r RedHat9) BuildUserData(userDataInput e2e.UserDataInput) ([]byte, error) return executeTemplate(rhel9CloudInit, data) } - -// AMI represents an ec2 Image. -type AMI struct { - ID string - CreatedAt time.Time -} - -// findLatestImage returns the most recent redhat image matching the amiPrefix and and arch -func findLatestImage(ctx context.Context, client *ec2.Client, amiPrefix, arch string) (string, error) { - var latestAMI AMI - - in := &ec2.DescribeImagesInput{ - Owners: []string{rhelAWSAccount}, - Filters: []types.Filter{{Name: aws.String("name"), Values: []string{amiPrefix}}, {Name: aws.String("architecture"), Values: []string{arch}}}, - MaxResults: aws.Int32(100), - } - - for { - l, err := client.DescribeImages(ctx, in) - if err != nil { - return "", err - } - - if paginationDone(in, l) { - break - } - - for _, i := range l.Images { - created, err := time.Parse(time.RFC3339Nano, *i.CreationDate) - if err != nil { - return "", err - } - if created.Compare(latestAMI.CreatedAt) > 0 { - latestAMI = AMI{ - ID: *i.ImageId, - CreatedAt: created, - } - } - } - - in.NextToken = l.NextToken - - if in.NextToken == nil { - break - } - } - - return latestAMI.ID, nil -} - -func paginationDone(in *ec2.DescribeImagesInput, out *ec2.DescribeImagesOutput) bool { - return (in.NextToken != nil && in.NextToken == out.NextToken) || len(out.Images) == 0 -} diff --git a/test/e2e/os/rocky.go b/test/e2e/os/rocky.go new file mode 100644 index 00000000..2380b5bf --- /dev/null +++ b/test/e2e/os/rocky.go @@ -0,0 +1,124 @@ +package os + +import ( + "context" + _ "embed" + "github.com/aws/aws-sdk-go-v2/service/ec2" + "github.com/aws/eks-hybrid/test/e2e" + + "github.com/aws/aws-sdk-go-v2/aws" +) + +const ( + awsMarketplaceAccount = "679593333241" + rocky9AmiId = "ami-08f2642bb132b988c" + rocky8AmiId = "ami-0f74cc83310468775" +) + +//go:embed testdata/rhel/8/cloud-init.txt +var rocky8CloudInit []byte + +//go:embed testdata/rhel/9/cloud-init.txt +var rocky9CloudInit []byte + +type Rocky8 struct { + amiArchitecture string + architecture architecture +} + +func NewRocky8AMD() *Rocky8 { + return &Rocky8{ + amiArchitecture: x8664Arch, + architecture: amd64, + } +} + +func NewRocky8ARM() *Rocky8 { + return &Rocky8{ + amiArchitecture: arm64Arch, + architecture: arm64, + } +} + +func (r Rocky8) Name() string { + return "rocky8-" + r.architecture.String() +} + +func (r Rocky8) InstanceType(region string) string { + return getInstanceTypeFromRegionAndArch(region, r.architecture) +} + +func (r Rocky8) AMIName(ctx context.Context, awsConfig aws.Config) (string, error) { + return findLatestImage(ctx, ec2.NewFromConfig(awsConfig), awsMarketplaceAccount, "Rocky-8*", r.amiArchitecture) +} + +func (r Rocky8) BuildUserData(userDataInput e2e.UserDataInput) ([]byte, error) { + if err := populateBaseScripts(&userDataInput); err != nil { + return nil, err + } + + // Rocky is based on RHEL. The following cloud-init templating works for Rocky + data := rhelCloudInitData{ + UserDataInput: userDataInput, + NodeadmUrl: userDataInput.NodeadmUrls.AMD, + SSMAgentURL: rhelSsmAgentAMD, + } + + if r.architecture.arm() { + data.NodeadmUrl = userDataInput.NodeadmUrls.ARM + data.SSMAgentURL = rhelSsmAgentARM + } + + return executeTemplate(rocky8CloudInit, data) +} + +type Rocky9 struct { + amiArchitecture string + architecture architecture +} + +func NewRocky9AMD() *Rocky9 { + return &Rocky9{ + amiArchitecture: x8664Arch, + architecture: amd64, + } +} + +func NewRocky9ARM() *Rocky9 { + return &Rocky9{ + amiArchitecture: arm64Arch, + architecture: arm64, + } +} + +func (r Rocky9) Name() string { + return "rocky9-" + r.architecture.String() +} + +func (r Rocky9) InstanceType(region string) string { + return getInstanceTypeFromRegionAndArch(region, r.architecture) +} + +func (r Rocky9) AMIName(ctx context.Context, awsConfig aws.Config) (string, error) { + return findLatestImage(ctx, ec2.NewFromConfig(awsConfig), awsMarketplaceAccount, "Rocky-9*", r.amiArchitecture) +} + +func (r Rocky9) BuildUserData(userDataInput e2e.UserDataInput) ([]byte, error) { + if err := populateBaseScripts(&userDataInput); err != nil { + return nil, err + } + + // Rocky is based on RHEL. The following cloud-init templating works for Rocky + data := rhelCloudInitData{ + UserDataInput: userDataInput, + NodeadmUrl: userDataInput.NodeadmUrls.AMD, + SSMAgentURL: rhelSsmAgentAMD, + } + + if r.architecture.arm() { + data.NodeadmUrl = userDataInput.NodeadmUrls.ARM + data.SSMAgentURL = rhelSsmAgentARM + } + + return executeTemplate(rocky9CloudInit, data) +} diff --git a/test/e2e/os/testdata/nodeadm-init.sh b/test/e2e/os/testdata/nodeadm-init.sh index e94ffcd3..cf277758 100755 --- a/test/e2e/os/testdata/nodeadm-init.sh +++ b/test/e2e/os/testdata/nodeadm-init.sh @@ -15,7 +15,7 @@ function run_debug(){ trap "run_debug" EXIT -# nodeadmin uninstall does not remove this folder, which contains the cilium/calico config +# nodeadm uninstall does not remove this folder, which contains the cilium/calico config # which kubelet uses to determine if a node is "Ready" # if we do not remove this folder, the node will flip to ready on re-join immediately # removing on boot instead of before rebooting to ensure containers are no longer running diff --git a/test/e2e/os/testdata/rhel/8/cloud-init.txt b/test/e2e/os/testdata/rhel/8/cloud-init.txt index 19c10434..b5377878 100644 --- a/test/e2e/os/testdata/rhel/8/cloud-init.txt +++ b/test/e2e/os/testdata/rhel/8/cloud-init.txt @@ -7,9 +7,11 @@ users: {{- if .RootPasswordHash }} hashed_passwd: {{ .RootPasswordHash }} {{- end }} +{{- if .RhelUsername }} rh_subscription: username: {{ .RhelUsername }} password: {{ .RhelPassword }} +{{- end }} package_update: true write_files: - content: | diff --git a/test/e2e/os/testdata/rhel/9/cloud-init.txt b/test/e2e/os/testdata/rhel/9/cloud-init.txt index 19c10434..b5377878 100644 --- a/test/e2e/os/testdata/rhel/9/cloud-init.txt +++ b/test/e2e/os/testdata/rhel/9/cloud-init.txt @@ -7,9 +7,11 @@ users: {{- if .RootPasswordHash }} hashed_passwd: {{ .RootPasswordHash }} {{- end }} +{{- if .RhelUsername }} rh_subscription: username: {{ .RhelUsername }} password: {{ .RhelPassword }} +{{- end }} package_update: true write_files: - content: | diff --git a/test/e2e/suite/nodeadm_test.go b/test/e2e/suite/nodeadm_test.go index 61588f99..90876a36 100644 --- a/test/e2e/suite/nodeadm_test.go +++ b/test/e2e/suite/nodeadm_test.go @@ -182,12 +182,16 @@ var _ = Describe("Hybrid Nodes", func() { osystem.NewRedHat8ARM(os.Getenv("RHEL_USERNAME"), os.Getenv("RHEL_PASSWORD")), osystem.NewRedHat9AMD(os.Getenv("RHEL_USERNAME"), os.Getenv("RHEL_PASSWORD")), osystem.NewRedHat9ARM(os.Getenv("RHEL_USERNAME"), os.Getenv("RHEL_PASSWORD")), + osystem.NewRocky8AMD(), + osystem.NewRocky8ARM(), + osystem.NewRocky9AMD(), + osystem.NewRocky9ARM(), } When("using peered VPC", func() { var test *peeredVPCTest - // Here is where we setup everything we need for the test. This includes + // Here is where we set up everything we need for the test. This includes // reading the setup output shared by the "before suite" code. This is the only place // that should be reading that global state, anything needed in the test code should // be passed down through "local" variable state. The global state should never be modified.