Skip to content

Commit

Permalink
Merge branch 'ami-controller' of https://github.com/engedaam/karpenter
Browse files Browse the repository at this point in the history
…into ami-controller
  • Loading branch information
engedaam committed May 13, 2024
2 parents d01482c + f220c7d commit 5cc58cf
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 447 deletions.
11 changes: 2 additions & 9 deletions pkg/apis/crds/karpenter.k8s.aws_ec2nodeclasses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -478,19 +478,12 @@ spec:
type
items:
description: |-
A node selector requirement with min values is a selector that contains values, a key, an operator that relates the key and values
and minValues that represent the requirement to have at least that many values.
A node selector requirement is a selector that contains values, a key, and an operator
that relates the key and values.
properties:
key:
description: The label key that the selector applies to.
type: string
minValues:
description: |-
This field is ALPHA and can be dropped or replaced at any time
MinValues is the minimum number of unique values required to define the flexibility of the specific requirement.
maximum: 50
minimum: 1
type: integer
operator:
description: |-
Represents a key's relationship to a set of values.
Expand Down
6 changes: 2 additions & 4 deletions pkg/apis/v1beta1/ec2nodeclass_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ limitations under the License.

package v1beta1

import (
corev1beta1 "sigs.k8s.io/karpenter/pkg/apis/v1beta1"
)
import v1 "k8s.io/api/core/v1"

// Subnet contains resolved Subnet selector values utilized for node launch
type Subnet struct {
Expand Down Expand Up @@ -48,7 +46,7 @@ type AMI struct {
Name string `json:"name,omitempty"`
// Requirements of the AMI to be utilized on an instance type
// +required
Requirements []corev1beta1.NodeSelectorRequirementWithMinValues `json:"requirements"`
Requirements []v1.NodeSelectorRequirement `json:"requirements"`
}

// EC2NodeClassStatus contains the resolved state of the EC2NodeClass
Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

109 changes: 22 additions & 87 deletions pkg/cloudprovider/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import (
"sigs.k8s.io/karpenter/pkg/events"
coreoptions "sigs.k8s.io/karpenter/pkg/operator/options"
"sigs.k8s.io/karpenter/pkg/operator/scheme"
"sigs.k8s.io/karpenter/pkg/scheduling"
coretest "sigs.k8s.io/karpenter/pkg/test"

. "github.com/onsi/ginkgo/v2"
Expand Down Expand Up @@ -116,41 +115,7 @@ var _ = Describe("CloudProvider", func() {
var nodePool *corev1beta1.NodePool
var nodeClaim *corev1beta1.NodeClaim
var _ = BeforeEach(func() {
nodeClass = test.EC2NodeClass(
v1beta1.EC2NodeClass{
Status: v1beta1.EC2NodeClassStatus{
InstanceProfile: "test-profile",
SecurityGroups: []v1beta1.SecurityGroup{
{
ID: "sg-test1",
Name: "securityGroup-test1",
},
{
ID: "sg-test2",
Name: "securityGroup-test2",
},
{
ID: "sg-test3",
Name: "securityGroup-test3",
},
},
Subnets: []v1beta1.Subnet{
{
ID: "subnet-test1",
Zone: "test-zone-1a",
},
{
ID: "subnet-test2",
Zone: "test-zone-1b",
},
{
ID: "subnet-test3",
Zone: "test-zone-1c",
},
},
},
},
)
nodeClass = test.EC2NodeClass()
nodePool = coretest.NodePool(corev1beta1.NodePool{
Spec: corev1beta1.NodePoolSpec{
Template: corev1beta1.NodeClaimTemplate{
Expand All @@ -177,40 +142,6 @@ var _ = Describe("CloudProvider", func() {
})
_, err := awsEnv.SubnetProvider.List(ctx, nodeClass) // Hydrate the subnet cache
Expect(err).To(BeNil())
amdRequirements := scheduling.NewRequirements()
amdRequirements.Add(scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureArm64))
nodeClass.Status.AMIs = []v1beta1.AMI{
{
ID: "ami-test1",
Requirements: scheduling.NewRequirements(
scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureAmd64),
scheduling.NewRequirement(v1beta1.LabelInstanceGPUCount, v1.NodeSelectorOpDoesNotExist),
scheduling.NewRequirement(v1beta1.LabelInstanceAcceleratorCount, v1.NodeSelectorOpDoesNotExist),
).NodeSelectorRequirements(),
},
{
ID: "ami-test2",
Requirements: scheduling.NewRequirements(
scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureAmd64),
scheduling.NewRequirement(v1beta1.LabelInstanceGPUCount, v1.NodeSelectorOpExists),
).NodeSelectorRequirements(),
},
{
ID: "ami-test3",
Requirements: scheduling.NewRequirements(
scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureAmd64),
scheduling.NewRequirement(v1beta1.LabelInstanceAcceleratorCount, v1.NodeSelectorOpExists),
).NodeSelectorRequirements(),
},
{
ID: "ami-test4",
Requirements: scheduling.NewRequirements(
scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureArm64),
scheduling.NewRequirement(v1beta1.LabelInstanceGPUCount, v1.NodeSelectorOpDoesNotExist),
scheduling.NewRequirement(v1beta1.LabelInstanceAcceleratorCount, v1.NodeSelectorOpDoesNotExist),
).NodeSelectorRequirements(),
},
}
Expect(awsEnv.InstanceTypesProvider.UpdateInstanceTypes(ctx)).To(Succeed())
Expect(awsEnv.InstanceTypesProvider.UpdateInstanceTypeOfferings(ctx)).To(Succeed())
})
Expand Down Expand Up @@ -660,7 +591,8 @@ var _ = Describe("CloudProvider", func() {
},
})
nodeClass.Status = v1beta1.EC2NodeClassStatus{
Subnets: []v1beta1.Subnet{
InstanceProfile: "test-profile",
Subnets: []v1beta1.Subnet{
{
ID: validSubnet1,
Zone: "zone-1",
Expand All @@ -678,15 +610,15 @@ var _ = Describe("CloudProvider", func() {
AMIs: []v1beta1.AMI{
{
ID: armAMIID,
Requirements: scheduling.NewRequirements(
scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureArm64),
).NodeSelectorRequirements(),
Requirements: []v1.NodeSelectorRequirement{
{Key: v1.LabelArchStable, Operator: v1.NodeSelectorOpIn, Values: []string{corev1beta1.ArchitectureArm64}},
},
},
{
ID: amdAMIID,
Requirements: scheduling.NewRequirements(
scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureAmd64),
).NodeSelectorRequirements(),
Requirements: []v1.NodeSelectorRequirement{
{Key: v1.LabelArchStable, Operator: v1.NodeSelectorOpIn, Values: []string{corev1beta1.ArchitectureAmd64}},
},
},
},
}
Expand Down Expand Up @@ -841,9 +773,9 @@ var _ = Describe("CloudProvider", func() {
nodeClass.Status.AMIs = []v1beta1.AMI{
{
ID: amdAMIID,
Requirements: scheduling.NewRequirements(
scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, corev1beta1.ArchitectureAmd64),
).NodeSelectorRequirements(),
Requirements: []v1.NodeSelectorRequirement{
{Key: v1.LabelArchStable, Operator: v1.NodeSelectorOpIn, Values: []string{corev1beta1.ArchitectureAmd64}},
},
},
}
ExpectApplied(ctx, env.Client, nodeClass)
Expand All @@ -853,10 +785,12 @@ var _ = Describe("CloudProvider", func() {
})
Context("Static Drift Detection", func() {
BeforeEach(func() {
armRequirements := scheduling.NewRequirements()
armRequirements.Add(scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, "arm64"))
amdRequirements := scheduling.NewRequirements()
amdRequirements.Add(scheduling.NewRequirement(v1.LabelArchStable, v1.NodeSelectorOpIn, "x86_64"))
armRequirements := []v1.NodeSelectorRequirement{
{Key: v1.LabelArchStable, Operator: v1.NodeSelectorOpIn, Values: []string{corev1beta1.ArchitectureArm64}},
}
amdRequirements := []v1.NodeSelectorRequirement{
{Key: v1.LabelArchStable, Operator: v1.NodeSelectorOpIn, Values: []string{corev1beta1.ArchitectureAmd64}},
}
nodeClass = &v1beta1.EC2NodeClass{
ObjectMeta: nodeClass.ObjectMeta,
Spec: v1beta1.EC2NodeClassSpec{
Expand Down Expand Up @@ -895,6 +829,7 @@ var _ = Describe("CloudProvider", func() {
},
},
Status: v1beta1.EC2NodeClassStatus{
InstanceProfile: "test-profile",
Subnets: []v1beta1.Subnet{
{
ID: validSubnet1,
Expand All @@ -913,11 +848,11 @@ var _ = Describe("CloudProvider", func() {
AMIs: []v1beta1.AMI{
{
ID: armAMIID,
Requirements: armRequirements.NodeSelectorRequirements(),
Requirements: armRequirements,
},
{
ID: amdAMIID,
Requirements: amdRequirements.NodeSelectorRequirements(),
Requirements: amdRequirements,
},
},
},
Expand Down Expand Up @@ -1166,12 +1101,12 @@ var _ = Describe("CloudProvider", func() {
},
},
Status: v1beta1.EC2NodeClassStatus{
AMIs: nodeClass.Status.AMIs,
SecurityGroups: []v1beta1.SecurityGroup{
{
ID: "sg-test1",
},
},
AMIs: nodeClass.Status.AMIs,
},
})
nodePool2 := coretest.NodePool(corev1beta1.NodePool{
Expand Down
9 changes: 7 additions & 2 deletions pkg/controllers/nodeclass/status/ami.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ import (
"time"

"github.com/samber/lo"
v1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

"github.com/aws/karpenter-provider-aws/pkg/apis/v1beta1"
"github.com/aws/karpenter-provider-aws/pkg/providers/amifamily"
corev1beta1 "sigs.k8s.io/karpenter/pkg/apis/v1beta1"
)

type AMI struct {
amiProvider amifamily.Provider
}

func (a *AMI) Reconcile(ctx context.Context, nodeClass *v1beta1.EC2NodeClass) (reconcile.Result, error) {
amis, err := a.amiProvider.Get(ctx, nodeClass, &amifamily.Options{})
amis, err := a.amiProvider.List(ctx, nodeClass)
if err != nil {
return reconcile.Result{}, err
}
Expand All @@ -41,7 +43,10 @@ func (a *AMI) Reconcile(ctx context.Context, nodeClass *v1beta1.EC2NodeClass) (r
return reconcile.Result{}, fmt.Errorf("no amis exist given constraints")
}
nodeClass.Status.AMIs = lo.Map(amis, func(ami amifamily.AMI, _ int) v1beta1.AMI {
reqs := ami.Requirements.NodeSelectorRequirements()
reqs := lo.Map(ami.Requirements.NodeSelectorRequirements(), func(item corev1beta1.NodeSelectorRequirementWithMinValues, _ int) v1.NodeSelectorRequirement {
return item.NodeSelectorRequirement
})

sort.Slice(reqs, func(i, j int) bool {
if len(reqs[i].Key) != len(reqs[j].Key) {
return len(reqs[i].Key) < len(reqs[j].Key)
Expand Down
Loading

0 comments on commit 5cc58cf

Please sign in to comment.