Skip to content

Commit f580791

Browse files
committed
Factorize all the code shared between install and uninstall
1 parent d67a083 commit f580791

File tree

4 files changed

+191
-268
lines changed

4 files changed

+191
-268
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Package clients provides shared AWS and Kubernetes client initialization
2+
// for the Karpenter install and uninstall commands.
3+
package clients
4+
5+
import (
6+
"context"
7+
"fmt"
8+
9+
awssdk "github.com/aws/aws-sdk-go-v2/aws"
10+
"github.com/aws/aws-sdk-go-v2/config"
11+
"github.com/aws/aws-sdk-go-v2/service/cloudformation"
12+
"github.com/aws/aws-sdk-go-v2/service/ec2"
13+
"github.com/aws/aws-sdk-go-v2/service/eks"
14+
"github.com/aws/aws-sdk-go-v2/service/sts"
15+
karpawsv1 "github.com/aws/karpenter-provider-aws/pkg/apis/v1"
16+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17+
"k8s.io/apimachinery/pkg/runtime"
18+
"k8s.io/apimachinery/pkg/runtime/schema"
19+
"k8s.io/cli-runtime/pkg/genericclioptions"
20+
"k8s.io/client-go/kubernetes"
21+
"k8s.io/client-go/kubernetes/scheme"
22+
"k8s.io/client-go/rest"
23+
"sigs.k8s.io/controller-runtime/pkg/client"
24+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
25+
karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1"
26+
27+
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/autoscaling/cluster/install/guess"
28+
)
29+
30+
// Clients holds all AWS and Kubernetes client instances needed for
31+
// Karpenter installation and uninstallation operations.
32+
type Clients struct {
33+
// AWS clients
34+
Config awssdk.Config
35+
CloudFormation *cloudformation.Client
36+
EC2 *ec2.Client
37+
EKS *eks.Client
38+
STS *sts.Client
39+
40+
// Kubernetes clients
41+
K8sClient client.Client // controller-runtime client
42+
K8sClientset *kubernetes.Clientset // typed Kubernetes client
43+
}
44+
45+
// Build creates AWS and Kubernetes clients for Karpenter operations.
46+
func Build(ctx context.Context, configFlags *genericclioptions.ConfigFlags, k8sClientset *kubernetes.Clientset) (*Clients, error) {
47+
awsConfig, err := config.LoadDefaultConfig(ctx)
48+
if err != nil {
49+
return nil, fmt.Errorf("failed to load AWS config: %w", err)
50+
}
51+
52+
sch := runtime.NewScheme()
53+
54+
if err = scheme.AddToScheme(sch); err != nil {
55+
return nil, fmt.Errorf("failed to add base scheme: %w", err)
56+
}
57+
58+
sch.AddKnownTypes(
59+
schema.GroupVersion{Group: "karpenter.sh", Version: "v1"},
60+
&karpv1.NodePool{},
61+
&karpv1.NodePoolList{},
62+
)
63+
metav1.AddToGroupVersion(sch, schema.GroupVersion{Group: "karpenter.sh", Version: "v1"})
64+
65+
sch.AddKnownTypes(
66+
schema.GroupVersion{Group: "karpenter.k8s.aws", Version: "v1"},
67+
&karpawsv1.EC2NodeClass{},
68+
&karpawsv1.EC2NodeClassList{},
69+
)
70+
metav1.AddToGroupVersion(sch, schema.GroupVersion{Group: "karpenter.k8s.aws", Version: "v1"})
71+
72+
restConfig, err := configFlags.ToRESTConfig()
73+
if err != nil {
74+
return nil, fmt.Errorf("failed to get REST config: %w", err)
75+
}
76+
77+
httpClient, err := rest.HTTPClientFor(restConfig)
78+
if err != nil {
79+
return nil, fmt.Errorf("unable to create http client: %w", err)
80+
}
81+
82+
mapper, err := apiutil.NewDynamicRESTMapper(restConfig, httpClient)
83+
if err != nil {
84+
return nil, fmt.Errorf("unable to instantiate mapper: %w", err)
85+
}
86+
87+
k8sClient, err := client.New(restConfig, client.Options{
88+
Scheme: sch,
89+
Mapper: mapper,
90+
})
91+
if err != nil {
92+
return nil, fmt.Errorf("failed to create Karpenter client: %w", err)
93+
}
94+
95+
return &Clients{
96+
Config: awsConfig,
97+
CloudFormation: cloudformation.NewFromConfig(awsConfig),
98+
EC2: ec2.NewFromConfig(awsConfig),
99+
EKS: eks.NewFromConfig(awsConfig),
100+
STS: sts.NewFromConfig(awsConfig),
101+
K8sClient: k8sClient,
102+
K8sClientset: k8sClientset,
103+
}, nil
104+
}
105+
106+
// GetClusterNameFromKubeconfig extracts the EKS cluster name from the current kubeconfig context.
107+
func GetClusterNameFromKubeconfig(ctx context.Context, configFlags *genericclioptions.ConfigFlags) (string, error) {
108+
kubeRawConfig, err := configFlags.ToRawKubeConfigLoader().RawConfig()
109+
if err != nil {
110+
return "", fmt.Errorf("failed to get raw kubeconfig: %w", err)
111+
}
112+
113+
kubeContext := ""
114+
if configFlags.Context != nil {
115+
kubeContext = *configFlags.Context
116+
}
117+
118+
return guess.GetClusterNameFromKubeconfig(ctx, kubeRawConfig, kubeContext), nil
119+
}

cmd/kubectl-datadog/autoscaling/cluster/common/helm/helm.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ import (
77
"errors"
88
"fmt"
99
"log"
10+
"os"
1011
"time"
1112

1213
"helm.sh/helm/v3/pkg/action"
1314
"helm.sh/helm/v3/pkg/chart/loader"
1415
"helm.sh/helm/v3/pkg/cli"
16+
"helm.sh/helm/v3/pkg/kube"
1517
"helm.sh/helm/v3/pkg/release"
1618
"helm.sh/helm/v3/pkg/storage/driver"
19+
"k8s.io/cli-runtime/pkg/genericclioptions"
1720
)
1821

1922
func CreateOrUpgrade(ctx context.Context, ac *action.Configuration, releaseName, namespace, chartRef, version string, values map[string]any) error {
@@ -152,3 +155,24 @@ func Uninstall(ctx context.Context, ac *action.Configuration, releaseName string
152155

153156
return nil
154157
}
158+
159+
// NewActionConfig creates a new Helm action configuration from kubeconfig flags.
160+
func NewActionConfig(configFlags *genericclioptions.ConfigFlags, namespace string) (*action.Configuration, error) {
161+
kubeConfig := ""
162+
if configFlags.KubeConfig != nil {
163+
kubeConfig = *configFlags.KubeConfig
164+
}
165+
kubeContext := ""
166+
if configFlags.Context != nil {
167+
kubeContext = *configFlags.Context
168+
}
169+
170+
restClientGetter := kube.GetConfig(kubeConfig, kubeContext, namespace)
171+
actionConfig := new(action.Configuration)
172+
173+
if err := actionConfig.Init(restClientGetter, namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
174+
return nil, fmt.Errorf("failed to initialize Helm configuration: %w", err)
175+
}
176+
177+
return actionConfig, nil
178+
}

0 commit comments

Comments
 (0)