From 8c1e136ff166728a76cb5491a9951a883422fd9b Mon Sep 17 00:00:00 2001 From: Alexander Demichev Date: Mon, 12 Oct 2020 20:29:28 +0200 Subject: [PATCH] Add support for dedicated instance tenancy --- pkg/actuators/machine/instances.go | 19 ++++++++ pkg/actuators/machine/instances_test.go | 43 +++++++++++++++++++ pkg/actuators/machine/stubs.go | 12 ++++++ .../v1beta1/awsproviderconfig_types.go | 16 +++++++ 4 files changed, 90 insertions(+) diff --git a/pkg/actuators/machine/instances.go b/pkg/actuators/machine/instances.go index 2218cb5af9..fe55a58eee 100644 --- a/pkg/actuators/machine/instances.go +++ b/pkg/actuators/machine/instances.go @@ -342,6 +342,25 @@ func launchInstance(machine *machinev1.Machine, machineProviderConfig *awsprovid } } + instanceTenancy := machineProviderConfig.Tenancy + + switch instanceTenancy { + case "": + // Do nothing when not set + case awsproviderv1.DefaultTenancy, awsproviderv1.DedicatedTenancy, awsproviderv1.HostTenancy: + if placement == nil { + placement = &ec2.Placement{} + } + tenancy := string(machineProviderConfig.Tenancy) + placement.Tenancy = &tenancy + default: + return nil, mapierrors.CreateMachine("invalid instance tenancy: %s. Allowed options are: %s,%s,%s", + instanceTenancy, + awsproviderv1.DefaultTenancy, + awsproviderv1.DedicatedTenancy, + awsproviderv1.HostTenancy) + } + inputConfig := ec2.RunInstancesInput{ ImageId: amiID, InstanceType: aws.String(machineProviderConfig.InstanceType), diff --git a/pkg/actuators/machine/instances_test.go b/pkg/actuators/machine/instances_test.go index ab69288acf..e30efa41b3 100644 --- a/pkg/actuators/machine/instances_test.go +++ b/pkg/actuators/machine/instances_test.go @@ -695,6 +695,49 @@ func TestLaunchInstance(t *testing.T) { name: "AMI not specified", providerConfig: stubPCAMI(awsproviderv1.AWSResourceReference{}), }, + { + name: "Dedicated instance tenancy", + providerConfig: stubDedicatedInstanceTenancy(), + runInstancesInput: &ec2.RunInstancesInput{ + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Name: aws.String(*providerConfig.IAMInstanceProfile.ID), + }, + ImageId: aws.String(*providerConfig.AMI.ID), + InstanceType: &providerConfig.InstanceType, + MinCount: aws.Int64(1), + MaxCount: aws.Int64(1), + KeyName: providerConfig.KeyName, + TagSpecifications: []*ec2.TagSpecification{{ + ResourceType: aws.String("instance"), + Tags: stubTagList, + }, { + ResourceType: aws.String("volume"), + Tags: stubTagList, + }}, + NetworkInterfaces: []*ec2.InstanceNetworkInterfaceSpecification{ + { + DeviceIndex: aws.Int64(providerConfig.DeviceIndex), + AssociatePublicIpAddress: providerConfig.PublicIP, + SubnetId: providerConfig.Subnet.ID, + Groups: []*string{ + aws.String("sg-00868b02fbe29de17"), + aws.String("sg-0a4658991dc5eb40a"), + aws.String("sg-009a70e28fa4ba84e"), + aws.String("sg-07323d56fb932c84c"), + aws.String("sg-08b1ffd32874d59a2"), + }, + }, + }, + UserData: aws.String(""), + Placement: &ec2.Placement{ + Tenancy: aws.String("dedicated"), + }, + }, + }, + { + name: "Dedicated instance tenancy", + providerConfig: stubInvalidInstanceTenancy(), + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/actuators/machine/stubs.go b/pkg/actuators/machine/stubs.go index 439d9c728c..fad8ac8878 100644 --- a/pkg/actuators/machine/stubs.go +++ b/pkg/actuators/machine/stubs.go @@ -216,6 +216,18 @@ func stubPCAMI(ami awsproviderv1.AWSResourceReference) *awsproviderv1.AWSMachine return pc } +func stubDedicatedInstanceTenancy() *awsproviderv1.AWSMachineProviderConfig { + pc := stubProviderConfig() + pc.Tenancy = awsproviderv1.DedicatedTenancy + return pc +} + +func stubInvalidInstanceTenancy() *awsproviderv1.AWSMachineProviderConfig { + pc := stubProviderConfig() + pc.Tenancy = "invalid" + return pc +} + func stubDescribeLoadBalancersOutput() *elbv2.DescribeLoadBalancersOutput { return &elbv2.DescribeLoadBalancersOutput{ LoadBalancers: []*elbv2.LoadBalancer{ diff --git a/pkg/apis/awsprovider/v1beta1/awsproviderconfig_types.go b/pkg/apis/awsprovider/v1beta1/awsproviderconfig_types.go index 2a958ccc8b..33c73845e0 100644 --- a/pkg/apis/awsprovider/v1beta1/awsproviderconfig_types.go +++ b/pkg/apis/awsprovider/v1beta1/awsproviderconfig_types.go @@ -88,6 +88,10 @@ type AWSMachineProviderConfig struct { // SpotMarketOptions allows users to configure instances to be run using AWS Spot instances. SpotMarketOptions *SpotMarketOptions `json:"spotMarketOptions,omitempty"` + + // Tenancy indicates if instance should run on shared or single-tenant hardware. There are + // supported 3 options: default, dedicated and host. + Tenancy InstanceTenancy `json:"tenancy,omitempty"` } // BlockDeviceMappingSpec describes a block device mapping @@ -235,6 +239,18 @@ type LoadBalancerReference struct { // an instance with load balancers specified in LoadBalancerNames type AWSLoadBalancerType string +// InstanceTenancy indicates if instance should run on shared or single-tenant hardware. +type InstanceTenancy string + +const ( + // DefaultTenancy instance runs on shared hardware + DefaultTenancy InstanceTenancy = "default" + // DedicatedTenancy instance runs on single-tenant hardware + DedicatedTenancy InstanceTenancy = "dedicated" + // HostTenancy instance runs on a Dedicated Host, which is an isolated server with configurations that you can control. + HostTenancy InstanceTenancy = "host" +) + // Possible values for AWSLoadBalancerType. Add to this list as other types // of load balancer are supported by the actuator. const (