Skip to content

Commit

Permalink
Added NodeClassSpec.UserData support
Browse files Browse the repository at this point in the history
  • Loading branch information
punkwalker committed May 10, 2024
1 parent ce0c764 commit 3622a60
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 18 deletions.
5 changes: 3 additions & 2 deletions cmd/version.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"encoding/json"
"fmt"

"github.com/spf13/cobra"
Expand All @@ -27,8 +28,8 @@ var versionCmd = &cobra.Command{
Date: date,
Commit: commit,
}

fmt.Printf("karpenter-generate version info: %#v\n", kgVersion)
verBytes, _ := json.Marshal(kgVersion)
fmt.Println(string(verBytes))
},
}

Expand Down
90 changes: 75 additions & 15 deletions pkg/karpenter/ec2nodeclass.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package karpenter

import (
"encoding/base64"
"strings"

ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
Expand All @@ -13,21 +14,41 @@ import (

type NodeGroup struct {
*ekstypes.Nodegroup
LtData *ec2types.ResponseLaunchTemplateData
LT *ec2types.ResponseLaunchTemplateData // LT Generated by MNG and used by ASG
CustomLT *ec2types.ResponseLaunchTemplateData // Custom LT provided to MNG
}

var (
NodeClassTypeMeta = metav1.TypeMeta{
Kind: "EC2NodeClass",
APIVersion: awskarpenter.SchemeGroupVersion.Identifier(),
}
CLUSTER_TAG map[string]string
)

func NewNodeGroup(ng ekstypes.Nodegroup) (*NodeGroup, error) {

newNodegroup := NodeGroup{
Nodegroup: &ng,
}

CLUSTER_TAG = map[string]string{
"kubernetes.io/cluster/" + *ng.ClusterName: "owned",
}

ec2Client := aws.NewEC2Client()
asgClient := aws.NewAutoscalingClient()

if ng.LaunchTemplate != nil {
customLT, err := ec2Client.DescribeLaunchTemplateVersions(
*ng.LaunchTemplate.Id,
*ng.LaunchTemplate.Version)
if err != nil {
return nil, aws.FormatErrorAsMessageOnly(err)
}
newNodegroup.CustomLT = customLT[0].LaunchTemplateData
}

asg, err := asgClient.DescribeAutoScalingGroups(*ng.Resources.AutoScalingGroups[0].Name)
if err != nil {
return nil, aws.FormatErrorAsMessageOnly(err)
Expand All @@ -40,10 +61,9 @@ func NewNodeGroup(ng ekstypes.Nodegroup) (*NodeGroup, error) {
return nil, aws.FormatErrorAsMessageOnly(err)
}

return &NodeGroup{
Nodegroup: &ng,
LtData: lt[0].LaunchTemplateData,
}, nil
newNodegroup.LT = lt[0].LaunchTemplateData

return &newNodegroup, nil
}

func (n *NodeGroup) GetEC2NodeClass() (awskarpenter.EC2NodeClass, error) {
Expand All @@ -59,7 +79,8 @@ func (n NodeGroup) Name() string {
}

func (n NodeGroup) AmiID() string {
return *n.LtData.ImageId
// TODO: implement logic if user wants to preserve AMID from MNG??
return *n.CustomLT.ImageId
}

func (n NodeGroup) NodeClassObjectMeta() metav1.ObjectMeta {
Expand All @@ -81,6 +102,7 @@ func (n NodeGroup) NodeClassSpec() awskarpenter.EC2NodeClassSpec {
Role: n.Role(),
SubnetSelectorTerms: n.SubnetSelectorTerms(),
SecurityGroupSelectorTerms: n.SecurityGroupSelectorTerms(),
UserData: n.UserData(),
Tags: n.FilteredTags(),
}
}
Expand All @@ -94,6 +116,16 @@ func (n NodeGroup) NodeClassSpec() awskarpenter.EC2NodeClassSpec {

func (n NodeGroup) FilteredTags() map[string]string {
filteredTags := map[string]string{}
if n.CustomLT != nil {
for _, tagspec := range n.CustomLT.TagSpecifications {
for _, tag := range tagspec.Tags {
if !strings.HasPrefix(*tag.Key, "aws:") {
filteredTags[*tag.Key] = *tag.Value
}
}
}
}

for key, val := range n.Tags {
if !strings.HasPrefix(key, "aws:") {
filteredTags[key] = val
Expand All @@ -119,6 +151,10 @@ func (n NodeGroup) AMIFamily() *string {
}
}

func (n NodeGroup) IsCustomAMIFamily() bool {
return n.AmiType == ekstypes.AMITypesCustom
}

func (n NodeGroup) AMISelectorTerms() []awskarpenter.AMISelectorTerm {
amiTerms := []awskarpenter.AMISelectorTerm{}
amiTerms = append(amiTerms, awskarpenter.AMISelectorTerm{
Expand Down Expand Up @@ -146,22 +182,46 @@ func (n NodeGroup) SubnetSelectorTerms() []awskarpenter.SubnetSelectorTerm {

func (n NodeGroup) SecurityGroupSelectorTerms() []awskarpenter.SecurityGroupSelectorTerm {
sgTerms := []awskarpenter.SecurityGroupSelectorTerm{}
ltSG := n.LtData.SecurityGroupIds

// For LTs created by simple MNG
for _, intf := range n.LtData.NetworkInterfaces {
for _, sg := range intf.Groups {
// For customLaunchTemplates
if n.CustomLT != nil {
ltSG := n.CustomLT.SecurityGroupIds
for _, sg := range ltSG {
sgTerms = append(sgTerms, awskarpenter.SecurityGroupSelectorTerm{
ID: sg,
})
}
}

// For customLaunchTemplates
for _, sg := range ltSG {
sgTerms = append(sgTerms, awskarpenter.SecurityGroupSelectorTerm{
ID: sg,
})
// TODO: Check how MNG handles SGs if Custom LT has Additional SGs
// For Cluster SG attached by MNG
for _, intf := range n.LT.NetworkInterfaces {
for _, sg := range intf.Groups {
sgTerms = append(sgTerms, awskarpenter.SecurityGroupSelectorTerm{
ID: sg,
})
}
}

return sgTerms
}

// Returns UserData for nodegroup if Custom Launch Template is used with MNG
func (n NodeGroup) UserData() *string {
if n.CustomLT != nil {
// Additional UserData for non-custom AMIs
if !n.IsCustomAMIFamily() {
decodedUserData, _ := base64.StdEncoding.DecodeString(*n.CustomLT.UserData)
userData := string(decodedUserData)
return &userData
}
// UserData for custom AMIs
decodedUserData, _ := base64.StdEncoding.DecodeString(*n.CustomLT.UserData)
userData := string(decodedUserData)
return &userData
}
return nil
}

// TODO: Implement logic for BlockDeviceMapping
// TODO: Implement logic for MetadataOptions
1 change: 0 additions & 1 deletion pkg/karpenter/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/aws/aws-sdk-go-v2/service/eks/types"
awskarpenter "github.com/aws/karpenter-provider-aws/pkg/apis/v1beta1"

"k8s.io/cli-runtime/pkg/printers"
sigkarpenter "sigs.k8s.io/karpenter/pkg/apis/v1beta1"
)
Expand Down

0 comments on commit 3622a60

Please sign in to comment.