Skip to content
Open
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
90 changes: 90 additions & 0 deletions modules/aws/eks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package aws

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eks"
"github.com/gruntwork-io/terratest/modules/testing"
"github.com/stretchr/testify/require"
)

// GetEksClusterE fetches information about an EKS cluster.
func GetEksClusterE(t testing.TestingT, region string, name string) (*eks.Cluster, error) {
client, err := NewEksClientE(t, region)
if err != nil {
return nil, err
}
input := &eks.DescribeClusterInput{
Name: aws.String(name),
}
output, err := client.DescribeCluster(input)
if err != nil {
return nil, err
}
return output.Cluster, nil
}

// GetEksCluster fetches information about an EKS cluster.
func GetEksCluster(t testing.TestingT, region string, name string) *eks.Cluster {
cluster, err := GetEksClusterE(t, region, name)
require.NoError(t, err)
return cluster
}

// CreateEksClusterE creates EKS cluster in the given region under the given name.
func CreateEksClusterE(t testing.TestingT, region string, name string, roleArn string, enablePrivateAccess bool, enablePublicAccess bool, subnets []*string, publicAccessCidrs []*string, securityGroupIds []*string) (*eks.Cluster, error) {
client := NewEksClient(t, region)
cluster, err := client.CreateCluster(&eks.CreateClusterInput{
Name: aws.String(name),
ResourcesVpcConfig: &eks.VpcConfigRequest{
EndpointPublicAccess: &enablePublicAccess,
EndpointPrivateAccess: &enablePrivateAccess,
SubnetIds: subnets,
SecurityGroupIds: securityGroupIds,
PublicAccessCidrs: publicAccessCidrs,
},
RoleArn: aws.String(roleArn),
})

if err != nil {
return nil, err
}
return cluster.Cluster, nil
}

// CreateEksCluster creates EKS cluster in the given region under the given name.
func CreateEksCluster(t testing.TestingT, region string, name string, roleArn string, enablePrivateAccess bool, enablePublicAccess bool, subnets []*string, publicAccessCidrs []*string, securityGroupIds []*string) *eks.Cluster {
cluster, err := CreateEksClusterE(t, region, name, roleArn, enablePrivateAccess, enablePublicAccess, subnets, publicAccessCidrs, securityGroupIds)
require.NoError(t, err)
return cluster
}

// DeleteEksClusterE deletes existing EKS cluster in the given region.
func DeleteEksClusterE(t testing.TestingT, region string, cluster *eks.Cluster) error {
client := NewEksClient(t, region)
_, err := client.DeleteCluster(&eks.DeleteClusterInput{
Name: aws.String(*cluster.Name),
})
return err
}

// DeleteEksCluster deletes existing EKS cluster in the given region.
func DeleteEksCluster(t testing.TestingT, region string, cluster *eks.Cluster) {
err := DeleteEksClusterE(t, region, cluster)
require.NoError(t, err)
}

// NewEksClient creates en EKS client.
func NewEksClient(t testing.TestingT, region string) *eks.EKS {
client, err := NewEksClientE(t, region)
require.NoError(t, err)
return client
}

// NewEcsClientE creates an ECS client.
func NewEksClientE(t testing.TestingT, region string) (*eks.EKS, error) {
sess, err := NewAuthenticatedSession(region)
if err != nil {
return nil, err
}
return eks.New(sess), nil
}
64 changes: 64 additions & 0 deletions modules/aws/eks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package aws

import (
"fmt"
"testing"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/gruntwork-io/terratest/modules/retry"
"github.com/stretchr/testify/assert"
)

func TestEksCluster(t *testing.T) {
t.Parallel()

// Setting the cluster to always run in us-east-1 and only the us-east-1a, us-east-1b, and us-east-1d subnets as there
// are seemingly randon subnet restrictions for EKS clusters.
region := GetRandomStableRegion(t, []string{"us-east-1"}, nil)
vpc, err := GetDefaultVpcE(t, region)
assert.Nil(t, err)

var subnetList []*string
for _, subnet := range vpc.Subnets {
if subnet.AvailabilityZone == "us-east-1a" || subnet.AvailabilityZone == "us-east-1b" || subnet.AvailabilityZone == "us-east-1d" {
subnetList = append(subnetList, aws.String(subnet.Id))
}
}

iamClient, err := NewIamClientE(t, region)
assert.Nil(t, err)

role, err := iamClient.GetRole(&iam.GetRoleInput{
RoleName: aws.String("AWSServiceRoleForOrganizations"),
})
assert.Nil(t, err)

clusterName := "terratest"
c1, err := CreateEksClusterE(t, region, clusterName, *role.Role.Arn, true, true, subnetList, []*string{aws.String("0.0.0.0/0")}, []*string{})
defer DeleteEksCluster(t, region, c1)

assert.Nil(t, err)
assert.Equal(t, "terratest", *c1.Name)

maxRetries := 60
sleepBetweenRetries := 30 * time.Second

status := retry.DoWithRetry(t, "Ensure cluster is active", maxRetries, sleepBetweenRetries, func() (string, error) {
cluster := GetEksCluster(t, region, clusterName)
status := *cluster.Status

if status != "ACTIVE" {
return "", fmt.Errorf("Got Cluster Status %s. Retrying.\n", *cluster.Status)
}
return status, nil
})

assert.Equal(t, "ACTIVE", status)

c2, err := GetEksClusterE(t, region, *c1.Name)

assert.Nil(t, err)
assert.Equal(t, "terratest", *c2.Name)
}
41 changes: 41 additions & 0 deletions modules/k8s/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package k8s
import (
"context"
"errors"
"fmt"
"time"

"github.com/stretchr/testify/require"
Expand All @@ -14,6 +15,46 @@ import (
"github.com/gruntwork-io/terratest/modules/testing"
)

// AssertAnyNodeHasLabelE will return an error if no nodes are found with the given label.
func AssertAnyNodeHasLabelE(t testing.TestingT, options *KubectlOptions, label string) error {
nodes, err := GetNodesByFilterE(t, options, metav1.ListOptions{
LabelSelector: label,
})

require.NoError(t, err)
if len(nodes) == 0 {
return fmt.Errorf("No nodes found with label %s", label)
}
return nil
}

// AssertAnyNodeHasLabel will fail the test if no nodes are found with the given label.
func AssertAnyNodeHasLabel(t testing.TestingT, options *KubectlOptions, label string) {
err := AssertAnyNodeHasLabelE(t, options, label)
require.NoError(t, err)
}

func AssertAnyNodeHasTaintE(t testing.TestingT, options *KubectlOptions, taintKey string, taintValue string, taintEffect corev1.TaintEffect) error {
nodes, err := GetNodesE(t, options)
require.NoError(t, err)

for _, node := range nodes {
for _, taint := range node.Spec.Taints {
if taint.Key == taintKey && taint.Value == taintValue && taint.Effect == taintEffect {
return nil
}
}
}

return fmt.Errorf("No nodes found with taint %s/%s/%s", taintKey, taintValue, taintEffect)
}

// AssertAnyNodeHasTaint will fail the test if no nodes are found with the given taint.
func AssertAnyNodeHasTaint(t testing.TestingT, options *KubectlOptions, taintKey string, taintValue string, taintEffect corev1.TaintEffect) {
err := AssertAnyNodeHasTaintE(t, options, taintKey, taintValue, taintEffect)
require.NoError(t, err)
}

// GetNodes queries Kubernetes for information about the worker nodes registered to the cluster. If anything goes wrong,
// the function will automatically fail the test.
func GetNodes(t testing.TestingT, options *KubectlOptions) []corev1.Node {
Expand Down