Skip to content

Commit

Permalink
Add support for BlockDeviceMapping and MetadataOption (#1)
Browse files Browse the repository at this point in the history
* feat: Add nodepool and nodeclass validtion
* feat: Add support for BlockDeviceMapping and MetadataOption
  • Loading branch information
punkwalker authored May 28, 2024
1 parent a33116b commit 22294fb
Show file tree
Hide file tree
Showing 16 changed files with 531 additions and 613 deletions.
4 changes: 1 addition & 3 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,4 @@ linters-settings:

issues:
exclude-dirs:
- dist
# TODO: remove when linting errors in existing code have been cleared
new-from-rev: HEAD~1
- dist
2 changes: 1 addition & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ brews:
name: homebrew-tap
branch: main
token: "{{ .Env.TAP_GITHUB_TOKEN }}"
folder: Formula
directory: Formula
homepage: https://github.com/punkwalker/karpenter-generate
description: A simple CLI tool to generate Karpenter CRDs from EKS Managed Node Groups
license: MIT-0
Expand Down
61 changes: 33 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
# `karpenter-generate`
# `karpenter-generate`
This is a simple CLI tool to generate AWS Karpenter Custom Kubernetes Resources (Nodepool & EC2NodeClass) from AWS EKS Managed Nodegroup information. The generated resources can be stored in as a yaml manifest file or can be directly applied to the cluster.

> [!WARNING]
> The tool can only generate ***v1beta*** resources for [Karpenter on AWS](https://karpenter.sh/).
> Compatible with Karpenter ***v.0.32.0*** onwards
## Example Usage
### For All Managed Nodegroups
The tool can be used without any flag and it will scan all the Managed Nodegroups in the cluster. The cluster to scan is decided based on current-context in kubeconfig
```bash
karpenter-generate
```
karpenter-generate --cluster <Cluster_Name> --karpenter-nodegroup fargate (If Karpenter is deployed on Fargate)
OR
karpenter-generate --cluster <Cluster_Name> --karpenter-nodegroup <Managed Node Group Name>
```

### For specific Managed Nodegroup
To generate Karpenter Custom Resources for a specific Managed Nodegroup.
```bash
karpenter-generate --nodegroup <Managed_Nodegroup_Name>
```

### For cluster other than current-context
To specifcy other cluster than current-context
```bash
karpenter-generate --cluster <Cluster_Name> --region <Region>
karpenter-generate --cluster <Cluster_Name> --karpenter-nodegroup fargate --nodegroup <Managed_Nodegroup_Name>
```

## Prerequisites
- Configured [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
- Valid kubeconfig store at `$HOME/.kube/config`
- Propely Configured [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)

## Installation
### MacOS & Linux
Use [Homebrew](https://brew.sh/) and run following command.
```bash
```
brew tap punkwalker/tap
brew install karpenter-generate
```
Expand All @@ -36,38 +37,42 @@ Downloaded archive file from release artifacts. Download the archive file from r

| OS | Arch | Download|
| ------ | ------ | ------ |
| Linux | AMD64/x86_64 | [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.3/karpenter-generate_Linux_x86_64.tar.gz)|
| | ARM64| [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.3/karpenter-generate_Linux_arm64.tar.gz)|
| Windows | AMD64/x86_64 | [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.3/karpenter-generate_Windows_x86_64.tar.gz)|
| | ARM64| [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.3/karpenter-generate_Windows_arm64.tar.gz)|
| Linux | AMD64/x86_64 | [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.4/karpenter-generate_Linux_x86_64.tar.gz)|
| | ARM64| [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.4/karpenter-generate_Linux_arm64.tar.gz)|
| Windows | AMD64/x86_64 | [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.4/karpenter-generate_Windows_x86_64.tar.gz)|
| | ARM64| [Link](https://github.com/punkwalker/karpenter-generate/releases/download/v0.0.4/karpenter-generate_Windows_arm64.tar.gz)|

After downloading the archive, extract it and copy the binary/executable to `/usr/local/bin` for Linux. For Windows, run the `karpenter-generate.exe` from extracted folder.

## Help
```bash
```
karpeter-generate --help
Description:
A CLI tool to generate Karpenter Custom Resources such as
Nodepools and EC2NodeClass from details of EKS Managed Nodegroup
Usage:
karpenter-generate [command]
karpenter-generate [flags]
karpenter-generate --cluster <Cluster Name> --karpenter-nodegroup <Karpenter Nodegroup Name> [flags]
Available Commands:
version Print the version and build information for karpenter-generate
Optional Flags:
--cluster string name of the EKS cluster
(default: from kubeconfig current-context)
Flags:
--cluster string name of the EKS cluster
--karpenter-nodegroup string name of the EKS managed nodegroup running Karpenter deployment or fargate
Optiona Flags:
--nodegroup string name of the EKS managed nodegroup
(default: all the nodegroups)
--region string the region to use, overrides config/env settings
(default: from kubeconfig current-context or AWS config)
(default: all the nodegroups expectthe one running Karpenter)
--region string region of EKS cluster, overrides AWS CLI configuration/ENV values
(default: AWS CLI configuration)
--profile string use the specific profile from your credential file
(default: from kubeconfig current-context or AWS config)
(default: AWS CLI configuration)
--output string output format (yaml or json)
(default: yaml)
-h, --help help for karpenter-generate
`
```

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var rootCmd = &cobra.Command{
Nodepools and EC2NodeClass from details of EKS Managed Nodegroup. Which will allow seamless migration to Karpenter.`,
SilenceUsage: true,
RunE: func(_ *cobra.Command, _ []string) error {
return run(opts)
return run()
},
}

Expand Down
64 changes: 44 additions & 20 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,22 @@ import (
"github.com/aws/aws-sdk-go-v2/service/eks/types"

"github.com/punkwalker/karpenter-generate/pkg/aws"
"github.com/punkwalker/karpenter-generate/pkg/karpenter"
"github.com/punkwalker/karpenter-generate/pkg/options"
"github.com/punkwalker/karpenter-generate/pkg/karpenteraws"
"github.com/punkwalker/karpenter-generate/pkg/printers"
)

func run(opts *options.Options) error {
func run() error {
aws.Init(opts)
opts.Parse()
var nodeGroups []types.Nodegroup
if err := opts.Parse(); err != nil {
return err
}

eksClient := aws.NewEKSClient()
if opts.NodegroupName != "" {
nodeGroup, err := eksClient.DescribeNodegroup(opts.ClusterName, opts.NodegroupName)
if err != nil {
return aws.FormatErrorAsMessageOnly(err)
}
nodeGroups = append(nodeGroups, *nodeGroup)
nodePools, nodeClasses, err := karpenter.Generate(&nodeGroups)
if err != nil {
return err
}
return karpenter.Print(nodePools, nodeClasses)
printer, err := printers.NewPrinter(printers.Output(opts.Output))
if err != nil {
return err
}

nodeGroups, err := eksClient.GetAllNodeGroups(opts)
nodeGroups, err := getNodegroups()
if err != nil {
return aws.FormatErrorAsMessageOnly(err)
}
Expand All @@ -38,9 +30,41 @@ func run(opts *options.Options) error {
return fmt.Errorf("no nodegroups found")
}

nodePools, nodeClasses, err := karpenter.Generate(&nodeGroups)
nodePools, nodeClasses, err := karpenteraws.Generate(&nodeGroups)
if err != nil {
return err
}
return karpenter.Print(nodePools, nodeClasses)
return printers.Print(printer, nodePools, nodeClasses)
}

func getNodegroups() ([]types.Nodegroup, error) {
var nodegroups []types.Nodegroup
var ngList []string
var err error

eksClient := aws.NewEKSClient()

if opts.NodegroupName != "" {
ngList = []string{opts.NodegroupName}
} else {
ngList, err = eksClient.ListNodegroups(opts.ClusterName)
if err != nil {
return nil, err
}
}

for _, ng := range ngList {
if opts.KarpenterNodegroupName != ng {
nodegroup, err := eksClient.DescribeNodegroup(opts.ClusterName, ng)
if err != nil {
return nil, err
}

if nodegroup.Status != "ACTIVE" {
return nil, fmt.Errorf(`nodegroup "%s" is not active, make sure all the nodegroups are in "ACTIVE" state`, ng)
}
nodegroups = append(nodegroups, *nodegroup)
}
}
return nodegroups, nil
}
25 changes: 11 additions & 14 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ require (
github.com/aws/aws-sdk-go-v2/service/eks v1.42.1
github.com/aws/karpenter-provider-aws v0.36.1
github.com/aws/smithy-go v1.20.2
github.com/samber/lo v1.39.0
github.com/spf13/cobra v1.8.0
k8s.io/api v0.30.0
k8s.io/apimachinery v0.30.0
k8s.io/cli-runtime v0.30.0
k8s.io/client-go v0.30.0
sigs.k8s.io/karpenter v0.36.1
)

Expand All @@ -33,23 +33,21 @@ require (
github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 // indirect
github.com/awslabs/amazon-eks-ami/nodeadm v0.0.0-20240229193347-cfab22a10647 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/evanphx/json-patch/v5 v5.8.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand All @@ -61,20 +59,17 @@ require (
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/samber/lo v1.39.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
Expand All @@ -84,13 +79,15 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/client-go v0.30.0 // indirect
k8s.io/cloud-provider v0.29.3 // indirect
k8s.io/csi-translation-lib v0.29.3 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect
knative.dev/pkg v0.0.0-20231010144348-ca8c009405dd // indirect
sigs.k8s.io/controller-runtime v0.17.2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // 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
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
Loading

0 comments on commit 22294fb

Please sign in to comment.