[CASCL-1304] Fix Fargate profile name in dd-cluster-info ConfigMap#3000
Conversation
The dd-cluster-info ConfigMap was writing an empty string as the Fargate profile-name bucket key, because `classifyNodeByLabel` read `eks.amazonaws.com/fargate-profile` from the Node. EKS stamps that label on the Pod scheduled on the Fargate node, not on the Node itself, so the read always returned "". Resolve the profile name by listing Pods filtered server-side with `LabelSelector: "eks.amazonaws.com/fargate-profile"`, building a nodeName→profileName index, and threading it through the classifier. A Fargate node with no Pod yet scheduled keeps falling into the empty-key bucket — acceptable for a one-shot informational snapshot. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3000 +/- ##
==========================================
+ Coverage 40.86% 40.90% +0.04%
==========================================
Files 334 334
Lines 28307 28327 +20
==========================================
+ Hits 11568 11588 +20
Misses 15960 15960
Partials 779 779
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
This comment has been minimized.
This comment has been minimized.
…esByNode The patch coverage gate failed at 72.72% (threshold 80%) because three new branches in classify.go were untested: - Classify error-return when fargateProfilesByNode fails. - The empty-NodeName skip path in fargateProfilesByNode. - The List error wrap path in fargateProfilesByNode. Adds two tests that close those branches via fake-clientset reactors and a pending pod fixture, mirroring the existing API-list-error pattern in guess/karpenter_test.go. fargateProfilesByNode now reaches 100% statement coverage and the package totals 93.9%.
dd-cluster-info ConfigMap
…-fargate-profile-in-cluster-info # Conflicts: # cmd/kubectl-datadog/autoscaling/cluster/common/clusterinfo/classify.go # cmd/kubectl-datadog/autoscaling/cluster/common/clusterinfo/classify_test.go
Continue the redistribution of `guess/` started by PRs #2980 and #3000: move every helper that operates on an EKS cluster object or the EKS API into a dedicated `common/eks/` package. After this commit, `common/eks/` contains: - authmode.go (was guess/clusterauthmode.go) - podidentityagent.go (was guess/ekspodidentityagent.go) - oidcprovider.go (was guess/oidcprovider.go) - privatesubnets.go (was guess/privatesubnets.go) Import alias `commoneks` is used to avoid colliding with the existing `github.com/aws/aws-sdk-go-v2/service/eks` (aliased `eks`). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…rn (#3012) * kubectl-datadog: extract EKS helpers to common/eks/ Continue the redistribution of `guess/` started by PRs #2980 and #3000: move every helper that operates on an EKS cluster object or the EKS API into a dedicated `common/eks/` package. After this commit, `common/eks/` contains: - authmode.go (was guess/clusterauthmode.go) - podidentityagent.go (was guess/ekspodidentityagent.go) - oidcprovider.go (was guess/oidcprovider.go) - privatesubnets.go (was guess/privatesubnets.go) Import alias `commoneks` is used to avoid colliding with the existing `github.com/aws/aws-sdk-go-v2/service/eks` (aliased `eks`). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: consolidate aws-auth into common/awsauth/ `common/aws/aws-auth.go` was misnamed: it manipulates a Kubernetes ConfigMap (`kube-system/aws-auth`), not an AWS-SDK resource. Together with `guess/aws-auth.go` (read-only presence check), it belongs in a dedicated `common/awsauth/` package: both files operate on the same ConfigMap. Function names lose the now-redundant `AwsAuth` prefix: - `IsAwsAuthConfigMapPresent` -> `IsConfigMapPresent` - `EnsureAwsAuthRole` -> `EnsureRole` - `RemoveAwsAuthRole` -> `RemoveRole` `common/aws/` now contains only cloudformation.go (pure AWS-SDK). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: fold clustername into common/clients/ The only caller of `guess.GetClusterNameFromKubeconfig` is the wrapper `clients.GetClusterNameFromKubeconfig` in `common/clients/clients.go`. Move the helper next to its caller as an unexported function `clusterNameFromKubeconfig`. The public API of `common/clients/` is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: carve out karpenter package Consolidate everything Karpenter-shaped into `common/karpenter/`, alongside the existing detection helper: - Intermediate model: NodePoolsSet, EC2NodeClass, NodePool, MetadataOptions, BlockDeviceMapping (from guess/nodepoolsset.go) - Producers from EKS node groups: GetNodeGroupsProperties (from guess/nodegroupproperties.go -> fromnodegroups.go) - Producers from running k8s Nodes: GetNodesProperties (from guess/nodesproperties.go -> fromnodes.go) - CR builders: CreateOrUpdateEC2NodeClass, CreateOrUpdateNodePool (from cluster/k8s/{ec2nodeclass,nodepool}.go) `cluster/k8s/` is gone (it was misnamed: those files build Karpenter CRDs, they aren't generic k8s primitives). `common/k8s/` keeps its narrow scope: generic object CRUD + deployment-finder. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: awsauth: extract ConfigMap name/namespace constants `kube-system` and `aws-auth` each appeared 5 times across the three functions. Promote them to package-level constants so the package's single-ConfigMap scope is explicit at a glance. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
…3000) * [CASCL-1304] Fix Fargate profile name in dd-cluster-info ConfigMap The dd-cluster-info ConfigMap was writing an empty string as the Fargate profile-name bucket key, because `classifyNodeByLabel` read `eks.amazonaws.com/fargate-profile` from the Node. EKS stamps that label on the Pod scheduled on the Fargate node, not on the Node itself, so the read always returned "". Resolve the profile name by listing Pods filtered server-side with `LabelSelector: "eks.amazonaws.com/fargate-profile"`, building a nodeName→profileName index, and threading it through the classifier. A Fargate node with no Pod yet scheduled keeps falling into the empty-key bucket — acceptable for a one-shot informational snapshot. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * [CASCL-1304] Cover error and empty-NodeName branches of fargateProfilesByNode The patch coverage gate failed at 72.72% (threshold 80%) because three new branches in classify.go were untested: - Classify error-return when fargateProfilesByNode fails. - The empty-NodeName skip path in fargateProfilesByNode. - The List error wrap path in fargateProfilesByNode. Adds two tests that close those branches via fake-clientset reactors and a pending pod fixture, mirroring the existing API-list-error pattern in guess/karpenter_test.go. fargateProfilesByNode now reaches 100% statement coverage and the package totals 93.9%. --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
…rn (#3012) * kubectl-datadog: extract EKS helpers to common/eks/ Continue the redistribution of `guess/` started by PRs #2980 and #3000: move every helper that operates on an EKS cluster object or the EKS API into a dedicated `common/eks/` package. After this commit, `common/eks/` contains: - authmode.go (was guess/clusterauthmode.go) - podidentityagent.go (was guess/ekspodidentityagent.go) - oidcprovider.go (was guess/oidcprovider.go) - privatesubnets.go (was guess/privatesubnets.go) Import alias `commoneks` is used to avoid colliding with the existing `github.com/aws/aws-sdk-go-v2/service/eks` (aliased `eks`). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: consolidate aws-auth into common/awsauth/ `common/aws/aws-auth.go` was misnamed: it manipulates a Kubernetes ConfigMap (`kube-system/aws-auth`), not an AWS-SDK resource. Together with `guess/aws-auth.go` (read-only presence check), it belongs in a dedicated `common/awsauth/` package: both files operate on the same ConfigMap. Function names lose the now-redundant `AwsAuth` prefix: - `IsAwsAuthConfigMapPresent` -> `IsConfigMapPresent` - `EnsureAwsAuthRole` -> `EnsureRole` - `RemoveAwsAuthRole` -> `RemoveRole` `common/aws/` now contains only cloudformation.go (pure AWS-SDK). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: fold clustername into common/clients/ The only caller of `guess.GetClusterNameFromKubeconfig` is the wrapper `clients.GetClusterNameFromKubeconfig` in `common/clients/clients.go`. Move the helper next to its caller as an unexported function `clusterNameFromKubeconfig`. The public API of `common/clients/` is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: carve out karpenter package Consolidate everything Karpenter-shaped into `common/karpenter/`, alongside the existing detection helper: - Intermediate model: NodePoolsSet, EC2NodeClass, NodePool, MetadataOptions, BlockDeviceMapping (from guess/nodepoolsset.go) - Producers from EKS node groups: GetNodeGroupsProperties (from guess/nodegroupproperties.go -> fromnodegroups.go) - Producers from running k8s Nodes: GetNodesProperties (from guess/nodesproperties.go -> fromnodes.go) - CR builders: CreateOrUpdateEC2NodeClass, CreateOrUpdateNodePool (from cluster/k8s/{ec2nodeclass,nodepool}.go) `cluster/k8s/` is gone (it was misnamed: those files build Karpenter CRDs, they aren't generic k8s primitives). `common/k8s/` keeps its narrow scope: generic object CRUD + deployment-finder. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * kubectl-datadog: awsauth: extract ConfigMap name/namespace constants `kube-system` and `aws-auth` each appeared 5 times across the three functions. Promote them to package-level constants so the package's single-ConfigMap scope is explicit at a glance. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
What does this PR do?
Fix the empty Fargate profile-name bucket key in the
dd-cluster-infoConfigMap written at the end of
kubectl datadog autoscaling cluster install.Before the fix, on a real EKS cluster the snapshot looked like:
After the fix:
Motivation
Root cause:
classifyNodeByLabel(introduced in #2945) read the Fargateprofile name from a label on the Node:
EKS does not put that label on the Node — it stamps it on the Pod
scheduled on the Fargate node. Verified on a live cluster: the Fargate
Node only carries
eks.amazonaws.com/compute-type=fargateand topologylabels; the hosted pod is the one carrying
eks.amazonaws.com/fargate-profile.So the read always returned an empty string, and the ConfigMap collapsed
every Fargate node into the
fargate: { "": [...] }bucket — making theprofile information unusable for the follow-up migration tooling.
Tracked in CASCL-1304.
Additional Notes
fargateProfilesByNodehelper lists Pods cluster-wide with aserver-side label-existence selector
(
LabelSelector: "eks.amazonaws.com/fargate-profile") and builds anodeName → profileNameindex. On non-Fargate clusters the filteredlist returns empty cheaply; the install path already does cluster-wide
Nodes.ListandDeployments.Listso the incrementalpods.listperm is small.
empty-key bucket — acceptable race window for a one-shot informational
snapshot.
Minimum Agent Versions
Describe your test plan
cmd/kubectl-datadog/autoscaling/cluster/common/clusterinfo/classify_test.go:TestClassify_AllBucketsByLabelupdated to put the profile label ona Pod scheduled on the Fargate node; preserves the empty-key fallback
coverage via the name-fallback case (no pod yet scheduled).
TestClassify_FargateMultipleProfiles(new) verifies two distinctFargate profiles produce two distinct bucket keys.
go test ./cmd/kubectl-datadog/autoscaling/cluster/common/clusterinfo/...lenaic-karpenter-test):fargatebucket keys againstaws eks list-fargate-profiles --cluster-name <cluster>.Checklist
bug,enhancement,refactoring,documentation,tooling, and/ordependenciesqa/skip-qalabel🤖 Generated with Claude Code