From 7f411ff1bf0e32ae6272bc9a0ba4e4807ec515d3 Mon Sep 17 00:00:00 2001 From: Carter McKinnon Date: Mon, 3 Jun 2024 16:44:40 -0700 Subject: [PATCH] Add bottlerocket user data format --- .../internal/deployers/eksapi/nodegroup.go | 8 ++- .../deployers/eksapi/templates/templates.go | 4 ++ .../unmanaged-nodegroup.yaml.template | 50 ++++++++++++------- .../userdata_bottlerocket.toml.template | 7 +++ .../internal/deployers/eksapi/userdata.go | 12 +++-- .../deployers/eksapi/userdata_test.go | 18 ++++--- 6 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 kubetest2/internal/deployers/eksapi/templates/userdata_bottlerocket.toml.template diff --git a/kubetest2/internal/deployers/eksapi/nodegroup.go b/kubetest2/internal/deployers/eksapi/nodegroup.go index 92ca118e2..323a9f06c 100644 --- a/kubetest2/internal/deployers/eksapi/nodegroup.go +++ b/kubetest2/internal/deployers/eksapi/nodegroup.go @@ -106,7 +106,7 @@ func (m *NodegroupManager) createManagedNodegroup(infra *Infrastructure, cluster func (m *NodegroupManager) createUnmanagedNodegroup(infra *Infrastructure, cluster *Cluster, opts *deployerOptions) error { stackName := m.getUnmanagedNodegroupStackName() klog.Infof("creating unmanaged nodegroup stack...") - userData, err := generateUserData(opts.UserDataFormat, cluster) + userData, userDataIsMimePart, err := generateUserData(opts.UserDataFormat, cluster) if err != nil { return err } @@ -145,6 +145,10 @@ func (m *NodegroupManager) createUnmanagedNodegroup(infra *Infrastructure, clust ParameterKey: aws.String("UserData"), ParameterValue: aws.String(userData), }, + { + ParameterKey: aws.String("UserDataIsMIMEPart"), + ParameterValue: aws.String(strconv.FormatBool(userDataIsMimePart)), + }, { ParameterKey: aws.String("ClusterName"), ParameterValue: aws.String(cluster.name), @@ -203,7 +207,7 @@ func (m *NodegroupManager) createUnmanagedNodegroup(infra *Infrastructure, clust func (m *NodegroupManager) createUnmanagedNodegroupWithEFA(infra *Infrastructure, cluster *Cluster, opts *deployerOptions) error { stackName := m.getUnmanagedNodegroupStackName() klog.Infof("creating unmanaged nodegroup with EFA stack...") - userData, err := generateUserData(opts.UserDataFormat, cluster) + userData, _, err := generateUserData(opts.UserDataFormat, cluster) if err != nil { return err } diff --git a/kubetest2/internal/deployers/eksapi/templates/templates.go b/kubetest2/internal/deployers/eksapi/templates/templates.go index a1bb4b4c0..29e14eaba 100644 --- a/kubetest2/internal/deployers/eksapi/templates/templates.go +++ b/kubetest2/internal/deployers/eksapi/templates/templates.go @@ -30,6 +30,10 @@ var ( //go:embed userdata_nodeadm.yaml.mimepart.template userDataNodeadmTemplate string UserDataNodeadm = template.Must(template.New("userDataNodeadm").Parse(userDataNodeadmTemplate)) + + //go:embed userdata_bottlerocket.toml.template + userDataBottlerocketTemplate string + UserDataBottlerocket = template.Must(template.New("userDataBottlerocket").Parse(userDataBottlerocketTemplate)) ) type UserDataTemplateData struct { diff --git a/kubetest2/internal/deployers/eksapi/templates/unmanaged-nodegroup.yaml.template b/kubetest2/internal/deployers/eksapi/templates/unmanaged-nodegroup.yaml.template index da3bb2079..ee819fdf5 100644 --- a/kubetest2/internal/deployers/eksapi/templates/unmanaged-nodegroup.yaml.template +++ b/kubetest2/internal/deployers/eksapi/templates/unmanaged-nodegroup.yaml.template @@ -45,6 +45,16 @@ Parameters: UserData: Type: String + UserDataIsMIMEPart: + Description: "User data should be embedded as a part of a multi-part MIME document" + Default: true + Type: String + AllowedValues: [true, false] + +Conditions: + IsUserDataMIMEPart: + !Equals [true, !Ref UserDataIsMIMEPart] + Resources: NodeInstanceProfile: Type: AWS::IAM::InstanceProfile @@ -97,24 +107,28 @@ Resources: KeyName: !Ref SSHKeyPair UserData: Fn::Base64: - Fn::Sub: | - Content-Type: multipart/mixed; boundary="BOUNDARY" - MIME-Version: 1.0 - - --BOUNDARY - ${UserData} - - --BOUNDARY - Content-Type: text/x-shellscript; charset="us-ascii" - MIME-Version: 1.0 - - #!/usr/bin/env bash - /opt/aws/bin/cfn-signal \ - --stack ${AWS::StackName} \ - --resource NodeGroup \ - --region ${AWS::Region} - - --BOUNDARY-- + Fn::If: + - IsUserDataMIMEPart + - Fn::Sub: | + Content-Type: multipart/mixed; boundary="BOUNDARY" + MIME-Version: 1.0 + + --BOUNDARY + ${UserData} + + --BOUNDARY + Content-Type: text/x-shellscript; charset="us-ascii" + MIME-Version: 1.0 + + #!/usr/bin/env bash + /opt/aws/bin/cfn-signal \ + --stack ${AWS::StackName} \ + --resource NodeGroup \ + --region ${AWS::Region} + + --BOUNDARY-- + - Fn::Sub: | + ${UserData} IamInstanceProfile: Arn: !GetAtt NodeInstanceProfile.Arn ImageId: !Ref AMIId diff --git a/kubetest2/internal/deployers/eksapi/templates/userdata_bottlerocket.toml.template b/kubetest2/internal/deployers/eksapi/templates/userdata_bottlerocket.toml.template new file mode 100644 index 000000000..8f169595f --- /dev/null +++ b/kubetest2/internal/deployers/eksapi/templates/userdata_bottlerocket.toml.template @@ -0,0 +1,7 @@ +[settings.kubernetes] +"cluster-name" = "{{.Name}}" +"api-server" = "{{.APIServerEndpoint}}" +"cluster-certificate" = "{{.CertificateAuthority}}" + +[settings.host-containers.admin] +"enabled" = true diff --git a/kubetest2/internal/deployers/eksapi/userdata.go b/kubetest2/internal/deployers/eksapi/userdata.go index 27f62f01b..ff7b7ef43 100644 --- a/kubetest2/internal/deployers/eksapi/userdata.go +++ b/kubetest2/internal/deployers/eksapi/userdata.go @@ -8,7 +8,8 @@ import ( "github.com/aws/aws-k8s-tester/kubetest2/internal/deployers/eksapi/templates" ) -func generateUserData(format string, cluster *Cluster) (string, error) { +func generateUserData(format string, cluster *Cluster) (string, bool, error) { + userDataIsMimePart := true var t *template.Template switch format { case "bootstrap.sh": @@ -16,8 +17,11 @@ func generateUserData(format string, cluster *Cluster) (string, error) { case "nodeadm": // TODO: replace the YAML template with proper usage of the nodeadm API go types t = templates.UserDataNodeadm + case "bottlerocket": + t = templates.UserDataBottlerocket + userDataIsMimePart = false default: - return "", fmt.Errorf("uknown user data format: '%s'", format) + return "", false, fmt.Errorf("uknown user data format: '%s'", format) } buf := bytes.Buffer{} if err := t.Execute(&buf, templates.UserDataTemplateData{ @@ -26,7 +30,7 @@ func generateUserData(format string, cluster *Cluster) (string, error) { CIDR: cluster.cidr, Name: cluster.name, }); err != nil { - return "", err + return "", false, err } - return buf.String(), nil + return buf.String(), userDataIsMimePart, nil } diff --git a/kubetest2/internal/deployers/eksapi/userdata_test.go b/kubetest2/internal/deployers/eksapi/userdata_test.go index 07c691b22..b71dd1cdf 100644 --- a/kubetest2/internal/deployers/eksapi/userdata_test.go +++ b/kubetest2/internal/deployers/eksapi/userdata_test.go @@ -38,26 +38,30 @@ spec: func Test_generateUserData(t *testing.T) { cases := []struct { - format string - expected string + format string + expected string + expectedIsMimePart bool }{ { - format: "bootstrap.sh", - expected: bootstrapShUserData, + format: "bootstrap.sh", + expected: bootstrapShUserData, + expectedIsMimePart: true, }, { - format: "nodeadm", - expected: nodeadmUserData, + format: "nodeadm", + expected: nodeadmUserData, + expectedIsMimePart: true, }, } for _, c := range cases { t.Run(c.format, func(t *testing.T) { - actual, err := generateUserData(c.format, &cluster) + actual, isMimePart, err := generateUserData(c.format, &cluster) if err != nil { t.Log(err) t.Error(err) } assert.Equal(t, c.expected, actual) + assert.Equal(t, c.expectedIsMimePart, isMimePart) }) } }