Skip to content
Merged
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
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,9 @@ e2e-test: ## Run e2e tests against cluster pointed to by ~/.kube/config
-count 1 \
-timeout 90m \
-v \
./suites/... \
./suites/integration/... \
--ginkgo.focus="${FOCUS}" \
--ginkgo.timeout=90m \
--ginkgo.v
--ginkgo.skip="${SKIP}"

.SILENT:
.PHONY: e2e-clean
Expand Down
23 changes: 19 additions & 4 deletions docs/contributing/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,22 @@ And use "EnvFile" GoLand plugin to read the env variables from the generated `.e

For larger changes it's recommended to run e2e suites on your local cluster.
E2E tests require a service network named `test-gateway` with cluster VPC associated to run.
You can either setup service network manually or use DEFAULT_SERVICE_NETWORK option when running controller locally. (e.g. `DEFAULT_SERVICE_NETWORK=test-gateway make run`)
You can either set up service network manually or use DEFAULT_SERVICE_NETWORK option when running controller locally. (e.g. `DEFAULT_SERVICE_NETWORK=test-gateway make run`)

```
REGION=us-west-2 make e2e-test
```

You can use `FOCUS` environment variable to run some specific test cases based on filter condition.
For the `RAM Share` test suite, which runs cross-account e2e tests, you will need a secondary account with a role that
can be assumed by the primary account during test execution.
You can create an IAM Role, with a Trust Policy allowing the primary account to assume it, via the AWS IAM Console.

```
export SECONDARY_ACCOUNT_TEST_ROLE_ARN=arn:aws:iam::000000000000:role/MyRole
REGION=us-west-2 make e2e-test
```

You can use the `FOCUS` environment variable to run some specific test cases based on filter condition.
You could assign the string in the Describe("xxxxxx") or It("xxxxxx") to the FOCUS environment variable to run the specific test cases.
```go
var _ = Describe("HTTPRoute path matches", func() {
Expand All @@ -136,13 +145,19 @@ var _ = Describe("HTTPRoute path matches", func() {
})
```

```
For example, to run the test case "HTTPRoute should support multiple path matches", you could run the following command:
```sh
export FOCUS="HTTPRoute should support multiple path matches"
export REGION=us-west-2
make e2e-test
```

For example, to run the test case "HTTPRoute should support multiple path matches", you could run the following command:
Conversely, you can use the `SKIP` environment variable to skip specific test cases.

For example, to skip the same test as above, you would run the following command:
```sh
export SKIP="HTTPRoute should support multiple path matches"
```

For more detail on filter condition for ginkgo
https://onsi.github.io/ginkgo/#focused-specs
Expand Down
26 changes: 16 additions & 10 deletions pkg/controllers/gateway_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ package controllers
import (
"context"
"fmt"

anv1alpha1 "github.com/aws/aws-application-networking-k8s/pkg/apis/applicationnetworking/v1alpha1"
"github.com/aws/aws-application-networking-k8s/pkg/aws/services"
"github.com/aws/aws-application-networking-k8s/pkg/controllers/eventhandlers"

"github.com/aws/aws-application-networking-k8s/pkg/aws"
Expand All @@ -41,7 +41,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

"github.com/aws/aws-application-networking-k8s/pkg/aws/services"
deploy "github.com/aws/aws-application-networking-k8s/pkg/deploy/lattice"
model "github.com/aws/aws-application-networking-k8s/pkg/model/lattice"
pkg_builder "sigs.k8s.io/controller-runtime/pkg/builder"
Expand Down Expand Up @@ -227,15 +226,22 @@ func (r *gatewayReconciler) reconcileUpsert(ctx context.Context, gw *gwv1beta1.G
snInfo, err := r.cloud.Lattice().FindServiceNetwork(ctx, gw.Name)
if err != nil {
if services.IsNotFoundError(err) {
if err = r.updateGatewayProgrammedStatus(ctx, "", gw, false); err != nil {
if err = r.updateGatewayProgrammedStatus(ctx, gw, gwv1.GatewayReasonPending, "VPC Lattice Service Network not found"); err != nil {
return lattice_runtime.NewRetryError()
}
return nil
}
if errors.Is(err, services.ErrNameConflict) {
if err = r.updateGatewayProgrammedStatus(ctx, gw, gwv1.GatewayReasonInvalid, "Found multiple VPC Lattice Service Networks matching Gateway name. Either ensure only one Service Network has a matching name, or use the Service Network's id as the Gateway name."); err != nil {
return lattice_runtime.NewRetryError()
}
return nil
}
return err
}

if err = r.updateGatewayProgrammedStatus(ctx, *snInfo.SvcNetwork.Arn, gw, true); err != nil {
err = r.updateGatewayProgrammedStatus(ctx, gw, gwv1.GatewayReasonProgrammed, fmt.Sprintf("aws-service-network-arn: %s", *snInfo.SvcNetwork.Arn))
if err != nil {
return err
}

Expand All @@ -244,27 +250,27 @@ func (r *gatewayReconciler) reconcileUpsert(ctx context.Context, gw *gwv1beta1.G

func (r *gatewayReconciler) updateGatewayProgrammedStatus(
ctx context.Context,
snArn string,
gw *gwv1beta1.Gateway,
programmed bool,
reason gwv1.GatewayConditionReason,
message string,
) error {
gwOld := gw.DeepCopy()

if programmed {
if reason == gwv1.GatewayReasonProgrammed {
gw.Status.Conditions = utils.GetNewConditions(gw.Status.Conditions, metav1.Condition{
Type: string(gwv1.GatewayConditionProgrammed),
Status: metav1.ConditionTrue,
ObservedGeneration: gw.Generation,
Reason: string(gwv1.GatewayReasonProgrammed),
Message: fmt.Sprintf("aws-gateway-arn: %s", snArn),
Message: message,
})
} else {
gw.Status.Conditions = utils.GetNewConditions(gw.Status.Conditions, metav1.Condition{
Type: string(gwv1.GatewayConditionProgrammed),
Status: metav1.ConditionFalse,
ObservedGeneration: gw.Generation,
Reason: string(gwv1.GatewayReasonPending),
Message: "VPC Lattice Gateway not found",
Reason: string(reason),
Message: message,
})
}

Expand Down
8 changes: 2 additions & 6 deletions pkg/model/lattice/targetgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/aws/aws-application-networking-k8s/pkg/model/core"
"github.com/aws/aws-application-networking-k8s/pkg/utils"
"github.com/aws/aws-sdk-go/service/vpclattice"
"math/rand"
)

const (
Expand Down Expand Up @@ -190,9 +189,6 @@ func TgNamePrefix(spec TargetGroupSpec) string {
func GenerateTgName(spec TargetGroupSpec) string {
// tg max name length 128
prefix := TgNamePrefix(spec)
randomSuffix := make([]rune, RandomSuffixLength)
for i := range randomSuffix {
randomSuffix[i] = rune(rand.Intn(26) + 'a')
}
return fmt.Sprintf("%s-%s", prefix, string(randomSuffix))
randomSuffix := utils.RandomAlphaString(RandomSuffixLength)
return fmt.Sprintf("%s-%s", prefix, randomSuffix)
}
9 changes: 9 additions & 0 deletions pkg/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"fmt"
"math/rand"
"strings"

"golang.org/x/exp/constraints"
Expand Down Expand Up @@ -85,6 +86,14 @@ func TargetRefToLatticeResourceName(
return "", fmt.Errorf("unsupported targetRef Kind: %s", targetRef.Kind)
}

func RandomAlphaString(length int) string {
str := make([]rune, length)
for i := range str {
str[i] = rune(rand.Intn(26) + 'a')
}
return string(str)
}

type none struct{}

type Set[T comparable] struct {
Expand Down
18 changes: 14 additions & 4 deletions test/pkg/test/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"time"

an_aws "github.com/aws/aws-application-networking-k8s/pkg/aws"
anaws "github.com/aws/aws-application-networking-k8s/pkg/aws"

"github.com/aws/aws-sdk-go/service/ec2"
"github.com/onsi/gomega/format"
Expand Down Expand Up @@ -50,6 +50,10 @@ import (
"github.com/aws/aws-application-networking-k8s/pkg/aws/services"
)

const (
K8sNamespace = "e2e-test"
)

type TestObject struct {
Type client.Object
ListType client.ObjectList
Expand Down Expand Up @@ -111,14 +115,14 @@ type Framework struct {
Ec2Client *ec2.EC2
GrpcurlRunner *corev1.Pod
DefaultTags services.Tags
Cloud an_aws.Cloud
Cloud anaws.Cloud
}

func NewFramework(ctx context.Context, log gwlog.Logger, testNamespace string) *Framework {
addOptionalCRDs(testScheme)
config.ConfigInit()
controllerRuntimeConfig := controllerruntime.GetConfigOrDie()
cloudConfig := an_aws.CloudConfig{
cloudConfig := anaws.CloudConfig{
VpcId: config.VpcID,
AccountId: config.AccountID,
Region: config.Region,
Expand All @@ -137,7 +141,7 @@ func NewFramework(ctx context.Context, log gwlog.Logger, testNamespace string) *
namespace: testNamespace,
controllerRuntimeConfig: controllerRuntimeConfig,
}
framework.Cloud = an_aws.NewDefaultCloud(framework.LatticeClient, cloudConfig)
framework.Cloud = anaws.NewDefaultCloud(framework.LatticeClient, cloudConfig)
framework.DefaultTags = framework.Cloud.DefaultTags()
SetDefaultEventuallyTimeout(3 * time.Minute)
SetDefaultEventuallyPollingInterval(10 * time.Second)
Expand Down Expand Up @@ -611,3 +615,9 @@ func (env *Framework) RunGrpcurlCmd(opts RunGrpcurlCmdOptions) (string, string,
func (env *Framework) SleepForRouteUpdate() {
time.Sleep(10 * time.Second)
}

func (env *Framework) NewTestTags() map[string]*string {
return env.Cloud.DefaultTagsMergedWith(map[string]*string{
anaws.TagBase + "TestSuite": aws.String(K8sNamespace),
})
}
Loading