Skip to content

Commit

Permalink
Merge pull request kubernetes#10384 from hakman/automated-cherry-pick…
Browse files Browse the repository at this point in the history
…-of-#10324-upstream-release-1.19

Automated cherry pick of kubernetes#10324: Add support for AWS IMDS v2
  • Loading branch information
k8s-ci-robot authored Dec 8, 2020
2 parents deecef2 + 858e23e commit 6bbc4ba
Show file tree
Hide file tree
Showing 60 changed files with 794 additions and 22 deletions.
6 changes: 6 additions & 0 deletions cloudmock/aws/mockec2/launch_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ func (m *MockEC2) CreateLaunchTemplate(request *ec2.CreateLaunchTemplateInput) (
name: request.LaunchTemplateName,
}

if request.LaunchTemplateData.MetadataOptions != nil {
resp.MetadataOptions = &ec2.LaunchTemplateInstanceMetadataOptions{
HttpTokens: request.LaunchTemplateData.MetadataOptions.HttpTokens,
HttpPutResponseHopLimit: request.LaunchTemplateData.MetadataOptions.HttpPutResponseHopLimit,
}
}
if request.LaunchTemplateData.Monitoring != nil {
resp.Monitoring = &ec2.LaunchTemplatesMonitoring{Enabled: request.LaunchTemplateData.Monitoring.Enabled}
}
Expand Down
11 changes: 11 additions & 0 deletions k8s/crds/kops.k8s.io_instancegroups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@ spec:
instanceInterruptionBehavior:
description: InstanceInterruptionBehavior defines if a spot instance should be terminated, hibernated, or stopped after interruption
type: string
instanceMetadata:
description: InstanceMetadata defines the EC2 instance metadata service options (AWS Only)
properties:
httpPutResponseHopLimit:
description: HTTPPutResponseHopLimit is the desired HTTP PUT response hop limit for instance metadata requests. The larger the number, the further instance metadata requests can travel. The default value is 1.
format: int64
type: integer
httpTokens:
description: HTTPTokens is the state of token usage for the instance metadata requests. If the parameter is not specified in the request, the default state is "optional".
type: string
type: object
instanceProtection:
description: InstanceProtection makes new instances in an autoscaling group protected from scale in
type: boolean
Expand Down
12 changes: 12 additions & 0 deletions pkg/apis/kops/instancegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ type InstanceGroupSpec struct {
InstanceInterruptionBehavior *string `json:"instanceInterruptionBehavior,omitempty"`
// CompressUserData compresses parts of the user data to save space
CompressUserData *bool `json:"compressUserData,omitempty"`
// InstanceMetadata defines the EC2 instance metadata service options (AWS Only)
InstanceMetadata *InstanceMetadataOptions `json:"instanceMetadata,omitempty"`
}

const (
Expand All @@ -182,6 +184,16 @@ const (
// SpotAllocationStrategies is a collection of supported strategies
var SpotAllocationStrategies = []string{SpotAllocationStrategyLowestPrices, SpotAllocationStrategyDiversified, SpotAllocationStrategyCapacityOptimized}

// InstanceMetadata defines the EC2 instance metadata service options (AWS Only)
type InstanceMetadataOptions struct {
// HTTPPutResponseHopLimit is the desired HTTP PUT response hop limit for instance metadata requests.
// The larger the number, the further instance metadata requests can travel. The default value is 1.
HTTPPutResponseHopLimit *int64 `json:"httpPutResponseHopLimit,omitempty"`
// HTTPTokens is the state of token usage for the instance metadata requests.
// If the parameter is not specified in the request, the default state is "optional".
HTTPTokens *string `json:"httpTokens,omitempty"`
}

// MixedInstancesPolicySpec defines the specification for an autoscaling group backed by a ec2 fleet
type MixedInstancesPolicySpec struct {
// Instances is a list of instance types which we are willing to run in the EC2 fleet
Expand Down
12 changes: 12 additions & 0 deletions pkg/apis/kops/v1alpha2/instancegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ type InstanceGroupSpec struct {
InstanceInterruptionBehavior *string `json:"instanceInterruptionBehavior,omitempty"`
// CompressUserData compresses parts of the user data to save space
CompressUserData *bool `json:"compressUserData,omitempty"`
// InstanceMetadata defines the EC2 instance metadata service options (AWS Only)
InstanceMetadata *InstanceMetadataOptions `json:"instanceMetadata,omitempty"`
}

const (
Expand All @@ -180,6 +182,16 @@ const (
// SpotAllocationStrategies is a collection of supported strategies
var SpotAllocationStrategies = []string{SpotAllocationStrategyLowestPrices, SpotAllocationStrategyDiversified, SpotAllocationStrategyCapacityOptimized}

// InstanceMetadata defines the EC2 instance metadata service options (AWS Only)
type InstanceMetadataOptions struct {
// HTTPPutResponseHopLimit is the desired HTTP PUT response hop limit for instance metadata requests.
// The larger the number, the further instance metadata requests can travel. The default value is 1.
HTTPPutResponseHopLimit *int64 `json:"httpPutResponseHopLimit,omitempty"`
// HTTPTokens is the state of token usage for the instance metadata requests.
// If the parameter is not specified in the request, the default state is "optional".
HTTPTokens *string `json:"httpTokens,omitempty"`
}

// MixedInstancesPolicySpec defines the specification for an autoscaling group backed by a ec2 fleet
type MixedInstancesPolicySpec struct {
// Instances is a list of instance types which we are willing to run in the EC2 fleet
Expand Down
50 changes: 50 additions & 0 deletions pkg/apis/kops/v1alpha2/zz_generated.conversion.go

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

31 changes: 31 additions & 0 deletions pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go

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

22 changes: 22 additions & 0 deletions pkg/apis/kops/validation/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,28 @@ func awsValidateInstanceGroup(ig *kops.InstanceGroup, cloud awsup.AWSCloud) fiel
allErrs = append(allErrs, awsValidateMixedInstancesPolicy(field.NewPath("spec", "mixedInstancesPolicy"), ig.Spec.MixedInstancesPolicy, ig, cloud)...)
}

if ig.Spec.InstanceMetadata != nil {
allErrs = append(allErrs, awsValidateInstanceMetadata(field.NewPath("spec", "instanceMetadata"), ig.Spec.InstanceMetadata)...)
}

return allErrs
}

func awsValidateInstanceMetadata(fieldPath *field.Path, instanceMetadata *kops.InstanceMetadataOptions) field.ErrorList {
allErrs := field.ErrorList{}

if instanceMetadata.HTTPTokens != nil {
allErrs = append(allErrs, IsValidValue(fieldPath.Child("httpTokens"), instanceMetadata.HTTPTokens, []string{"optional", "required"})...)
}

if instanceMetadata.HTTPPutResponseHopLimit != nil {
httpPutResponseHopLimit := fi.Int64Value(instanceMetadata.HTTPPutResponseHopLimit)
if httpPutResponseHopLimit < 1 || httpPutResponseHopLimit > 64 {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("httpPutResponseHopLimit"), instanceMetadata.HTTPPutResponseHopLimit,
"HTTPPutResponseLimit must be a value between 1 and 64"))
}
}

return allErrs
}

Expand Down
45 changes: 45 additions & 0 deletions pkg/apis/kops/validation/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,48 @@ func TestValidateInstanceGroupSpec(t *testing.T) {
testErrors(t, g.Input, errs, g.ExpectedErrors)
}
}

func TestInstanceMetadataOptions(t *testing.T) {
cloud := awsup.BuildMockAWSCloud("us-east-1", "abc")

tests := []struct {
ig *kops.InstanceGroup
expected []string
}{
{
ig: &kops.InstanceGroup{
ObjectMeta: v1.ObjectMeta{
Name: "some-ig",
},
Spec: kops.InstanceGroupSpec{
Role: "Node",
InstanceMetadata: &kops.InstanceMetadataOptions{
HTTPPutResponseHopLimit: fi.Int64(1),
HTTPTokens: fi.String("abc"),
},
},
},
expected: []string{"Unsupported value::spec.instanceMetadata.httpTokens"},
},
{
ig: &kops.InstanceGroup{
ObjectMeta: v1.ObjectMeta{
Name: "some-ig",
},
Spec: kops.InstanceGroupSpec{
Role: "Node",
InstanceMetadata: &kops.InstanceMetadataOptions{
HTTPPutResponseHopLimit: fi.Int64(-1),
HTTPTokens: fi.String("required"),
},
},
},
expected: []string{"Invalid value::spec.instanceMetadata.httpPutResponseHopLimit"},
},
}

for _, test := range tests {
errs := ValidateInstanceGroup(test.ig, cloud)
testErrors(t, test.ig.ObjectMeta.Name, errs, test.expected)
}
}
31 changes: 31 additions & 0 deletions pkg/apis/kops/zz_generated.deepcopy.go

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

47 changes: 29 additions & 18 deletions pkg/model/awsmodel/autoscalinggroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,26 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.ModelBuilde
// LaunchConfiguration as an anonymous field, bit given up the task dependency walker works this caused issues, due
// to the creation of a implicit dependency
lt := &awstasks.LaunchTemplate{
Name: fi.String(name),
Lifecycle: b.Lifecycle,
AssociatePublicIP: lc.AssociatePublicIP,
BlockDeviceMappings: lc.BlockDeviceMappings,
IAMInstanceProfile: lc.IAMInstanceProfile,
ImageID: lc.ImageID,
InstanceMonitoring: lc.InstanceMonitoring,
InstanceType: lc.InstanceType,
RootVolumeOptimization: lc.RootVolumeOptimization,
RootVolumeSize: lc.RootVolumeSize,
RootVolumeIops: lc.RootVolumeIops,
RootVolumeType: lc.RootVolumeType,
RootVolumeEncryption: lc.RootVolumeEncryption,
SSHKey: lc.SSHKey,
SecurityGroups: lc.SecurityGroups,
Tags: tags,
Tenancy: lc.Tenancy,
UserData: lc.UserData,
Name: fi.String(name),
Lifecycle: b.Lifecycle,
AssociatePublicIP: lc.AssociatePublicIP,
BlockDeviceMappings: lc.BlockDeviceMappings,
IAMInstanceProfile: lc.IAMInstanceProfile,
ImageID: lc.ImageID,
InstanceMonitoring: lc.InstanceMonitoring,
InstanceType: lc.InstanceType,
RootVolumeOptimization: lc.RootVolumeOptimization,
RootVolumeSize: lc.RootVolumeSize,
RootVolumeIops: lc.RootVolumeIops,
RootVolumeType: lc.RootVolumeType,
RootVolumeEncryption: lc.RootVolumeEncryption,
SSHKey: lc.SSHKey,
SecurityGroups: lc.SecurityGroups,
Tags: tags,
Tenancy: lc.Tenancy,
UserData: lc.UserData,
HTTPTokens: lc.HTTPTokens,
HTTPPutResponseHopLimit: lc.HTTPPutResponseHopLimit,
}
// When using a MixedInstances ASG, AWS requires the SpotPrice be defined on the ASG
// rather than the LaunchTemplate or else it returns this error:
Expand Down Expand Up @@ -215,6 +217,15 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchConfigurationTask(c *fi.ModelB
SecurityGroups: []*awstasks.SecurityGroup{sgLink},
}

t.HTTPTokens = fi.String("optional")
if ig.Spec.InstanceMetadata != nil && ig.Spec.InstanceMetadata.HTTPTokens != nil {
t.HTTPTokens = ig.Spec.InstanceMetadata.HTTPTokens
}
t.HTTPPutResponseHopLimit = fi.Int64(1)
if ig.Spec.InstanceMetadata != nil && ig.Spec.InstanceMetadata.HTTPPutResponseHopLimit != nil {
t.HTTPPutResponseHopLimit = ig.Spec.InstanceMetadata.HTTPPutResponseHopLimit
}

if b.APILoadBalancerClass() == kops.LoadBalancerClassNetwork {
for _, id := range b.Cluster.Spec.API.LoadBalancer.AdditionalSecurityGroups {
sgTask := &awstasks.SecurityGroup{
Expand Down
Loading

0 comments on commit 6bbc4ba

Please sign in to comment.