Skip to content

✨ WIP: Initial dedicated hosts implementation #5398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions .archive/unmanaged_CAPI_dedicated_host.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//go:build e2e
// +build e2e

/*
Copyright 2025 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package unmanaged

import (
"context"

"github.com/gofrs/flock"
"github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"

"sigs.k8s.io/cluster-api-provider-aws/v2/test/e2e/shared"
capi_e2e "sigs.k8s.io/cluster-api/test/e2e"
)

// setupNamespace initializes the namespace for the test.
func setupNamespace(ctx context.Context, e2eCtx *shared.E2EContext) *corev1.Namespace {
Expect(e2eCtx.Environment.BootstrapClusterProxy).ToNot(BeNil(), "Invalid argument. BootstrapClusterProxy can't be nil")
return shared.SetupSpecNamespace(ctx, "capa-dedicate-host", e2eCtx)
}

// setupRequiredResources allocates the required resources for the test.
func setupRequiredResources(e2eCtx *shared.E2EContext) *shared.TestResource {
requiredResources := &shared.TestResource{
EC2Normal: 2 * e2eCtx.Settings.InstanceVCPU,
IGW: 1,
NGW: 1,
VPC: 1,
ClassicLB: 1,
EIP: 3,
EventBridgeRules: 50,
}
requiredResources.WriteRequestedResources(e2eCtx, "capa-dedicated-hosts-test")

Expect(shared.AcquireResources(requiredResources, ginkgo.GinkgoParallelProcess(), flock.New(shared.ResourceQuotaFilePath))).To(Succeed())
return requiredResources
}

// releaseResources releases the resources allocated for the test.
func releaseResources(requiredResources *shared.TestResource, e2eCtx *shared.E2EContext) {
shared.ReleaseResources(requiredResources, ginkgo.GinkgoParallelProcess(), flock.New(shared.ResourceQuotaFilePath))
}

// runQuickStartSpec executes the QuickStartSpec test.
func runQuickStartSpec(e2eCtx *shared.E2EContext) {
capi_e2e.QuickStartSpec(context.TODO(), func() capi_e2e.QuickStartSpecInput {
return capi_e2e.QuickStartSpecInput{
E2EConfig: e2eCtx.E2EConfig,
ClusterctlConfigPath: e2eCtx.Environment.ClusterctlConfigPath,
BootstrapClusterProxy: e2eCtx.Environment.BootstrapClusterProxy,
ArtifactFolder: e2eCtx.Settings.ArtifactFolder,
SkipCleanup: e2eCtx.Settings.SkipCleanup,
}
})
}

// cleanupNamespace cleans up the namespace and dumps resources.
func cleanupNamespace(ctx context.Context, namespace *corev1.Namespace, e2eCtx *shared.E2EContext) {
shared.DumpSpecResourcesAndCleanup(ctx, "", namespace, e2eCtx)
}

var _ = ginkgo.Context("[unmanaged] [dedicated-host]", func() {
var (
namespace *corev1.Namespace
ctx context.Context
requiredResources *shared.TestResource
dedicatedHostID string
)

ginkgo.BeforeEach(func() {
ctx = context.TODO()
namespace = setupNamespace(ctx, e2eCtx)
dedicatedHostID, _ = shared.GetDedicatedHost(e2eCtx)
})

ginkgo.Describe("Running the dedicated-hosts spec", func() {
ginkgo.BeforeEach(func() {
requiredResources = setupRequiredResources(e2eCtx)
// e2eCtx.Settings.DedicatedHostID = dedicatedHostID
})

ginkgo.It("should run the QuickStartSpec", func() {
runQuickStartSpec(e2eCtx)
})

ginkgo.AfterEach(func() {
shared.DeleteDedicatedHost(e2eCtx, dedicatedHostID)
releaseResources(requiredResources, e2eCtx)
})
})

ginkgo.AfterEach(func() {
cleanupNamespace(ctx, namespace, e2eCtx)
})
})
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ envfile
# kubeconfigs
kind.kubeconfig
minikube.kubeconfig
capi-test.kubeconfig
kubeconfig
!kubeconfig/

Expand Down Expand Up @@ -63,3 +64,5 @@ dist
_artifacts
awsiamconfiguration.yaml
cloudformation.yaml
test-cluster.yaml
__debug*
2 changes: 2 additions & 0 deletions api/v1beta1/awscluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
dst.Status.Bastion.NetworkInterfaceType = restored.Status.Bastion.NetworkInterfaceType
dst.Status.Bastion.CapacityReservationID = restored.Status.Bastion.CapacityReservationID
dst.Status.Bastion.MarketType = restored.Status.Bastion.MarketType
dst.Status.Bastion.HostAffinity = restored.Status.Bastion.HostAffinity
dst.Status.Bastion.HostID = restored.Status.Bastion.HostID
}
dst.Spec.Partition = restored.Spec.Partition

Expand Down
5 changes: 5 additions & 0 deletions api/v1beta1/awsmachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ func (src *AWSMachine) ConvertTo(dstRaw conversion.Hub) error {
}
}

dst.Spec.HostAffinity = restored.Spec.HostAffinity
dst.Spec.HostID = restored.Spec.HostID

return nil
}

Expand Down Expand Up @@ -119,6 +122,8 @@ func (r *AWSMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.Template.Spec.ElasticIPPool.PublicIpv4PoolFallBackOrder = restored.Spec.Template.Spec.ElasticIPPool.PublicIpv4PoolFallBackOrder
}
}
dst.Spec.Template.Spec.HostAffinity = restored.Spec.Template.Spec.HostAffinity
dst.Spec.Template.Spec.HostID = restored.Spec.Template.Spec.HostID

return nil
}
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta1/zz_generated.conversion.go

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

10 changes: 10 additions & 0 deletions api/v1beta2/awsmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@ type AWSMachineSpec struct {
// If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
// +optional
MarketType MarketType `json:"marketType,omitempty"`

// HostID specifies the Dedicated Host on which the instance should be launched.
// +optional
HostID *string `json:"hostId,omitempty"`

// Affinity specifies the dedicated host affinity setting for the instance.
// When affinity is set to Host, an instance launched onto a specific host always restarts on the same host if stopped.
// +optional
// +kubebuilder:validation:Enum:=Defailt;Host

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// +kubebuilder:validation:Enum:=Defailt;Host
// +kubebuilder:validation:Enum:=Default;Host

HostAffinity *string `json:"hostAffinity,omitempty"`
}

// CloudInit defines options related to the bootstrapping systems where
Expand Down
8 changes: 8 additions & 0 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ type Instance struct {
// If marketType is not specified and spotMarketOptions is provided, the marketType defaults to "Spot".
// +optional
MarketType MarketType `json:"marketType,omitempty"`

// HostID specifies the dedicated host on which the instance should be launched
// +optional
HostID *string `json:"hostID,omitempty"`

// Affinity specifies the dedicated host affinity setting for the instance.
// +optional
HostAffinity *string `json:"hostAffinity,omitempty"`
}

// MarketType describes the market type of an Instance
Expand Down
20 changes: 20 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,14 @@ spec:
description: Specifies whether enhanced networking with ENA is
enabled.
type: boolean
hostAffinity:
description: Affinity specifies the dedicated host affinity setting
for the instance.
type: string
hostID:
description: HostID specifies the dedicated host on which the
instance should be launched
type: string
iamProfile:
description: The name of the IAM instance profile associated with
the instance, if applicable.
Expand Down Expand Up @@ -3224,6 +3232,14 @@ spec:
description: Specifies whether enhanced networking with ENA is
enabled.
type: boolean
hostAffinity:
description: Affinity specifies the dedicated host affinity setting
for the instance.
type: string
hostID:
description: HostID specifies the dedicated host on which the
instance should be launched
type: string
iamProfile:
description: The name of the IAM instance profile associated with
the instance, if applicable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2103,6 +2103,14 @@ spec:
description: Specifies whether enhanced networking with ENA is
enabled.
type: boolean
hostAffinity:
description: Affinity specifies the dedicated host affinity setting
for the instance.
type: string
hostID:
description: HostID specifies the dedicated host on which the
instance should be launched
type: string
iamProfile:
description: The name of the IAM instance profile associated with
the instance, if applicable.
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,18 @@ spec:
- message: allowed values are 'none' and 'amazon-pool'
rule: self in ['none','amazon-pool']
type: object
hostAffinity:
description: |-
Affinity specifies the dedicated host affinity setting for the instance.
When affinity is set to Host, an instance launched onto a specific host always restarts on the same host if stopped.
enum:
- Defailt
- Host
type: string
hostId:
description: HostID specifies the Dedicated Host on which the instance
should be launched.
type: string
iamInstanceProfile:
description: IAMInstanceProfile is a name of an IAM instance profile
to assign to the instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,18 @@ spec:
- message: allowed values are 'none' and 'amazon-pool'
rule: self in ['none','amazon-pool']
type: object
hostAffinity:
description: |-
Affinity specifies the dedicated host affinity setting for the instance.
When affinity is set to Host, an instance launched onto a specific host always restarts on the same host if stopped.
enum:
- Defailt
- Host
type: string
hostId:
description: HostID specifies the Dedicated Host on which
the instance should be launched.
type: string
iamInstanceProfile:
description: IAMInstanceProfile is a name of an IAM instance
profile to assign to the instance
Expand Down
6 changes: 3 additions & 3 deletions devbox.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [
"[email protected]",
"kind@latest",
"docker@latest",
"jq@latest",
Expand All @@ -11,7 +10,8 @@
"tilt@latest",
"awscli2@latest",
"direnv@latest",
"kustomize@latest"
"[email protected]",
"[email protected]"
],
"shell": {
"init_hook": [
Expand All @@ -27,4 +27,4 @@
]
}
}
}
}
Loading