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
35 changes: 2 additions & 33 deletions openshift-tests/ccm-aws-tests/e2e/aws/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package aws
import (
"context"
"fmt"
"regexp"
"strings"
"time"

Expand All @@ -15,19 +14,10 @@ import (
elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
"github.com/openshift/cluster-cloud-controller-manager-operator/openshift-tests/ccm-aws-tests/e2e/common"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/test/e2e/framework"
)

// awsRegionPattern matches valid AWS region names across all partitions:
// standard (aws: us-east-1), China (aws-cn: cn-northwest-1),
// GovCloud (aws-us-gov: us-gov-west-1), European Sovereign Cloud (aws-eusc: eusc-de-east-1),
// and ISO/ISOB (aws-iso/iso-b: us-isob-east-1).
var awsRegionPattern = regexp.MustCompile(`^[a-z]{2,4}(?:-[a-z0-9]+)+-\d+$`)

// AWS helpers

// loadAWSConfig loads the default AWS SDK configuration.
// The region is discovered from the Infrastructure object and forced
// to the client (from test binar), falling back to the cfg.Region when it is valid,
Expand All @@ -42,38 +32,17 @@ func loadAWSConfig(ctx context.Context) (aws.Config, error) {

// Using region defined in the Infrastructure object as source of thruth
// to build the AWS client config.
region, err := getRegionFromInfrastructure(ctx)
region, err := common.GetRegionFromInfrastructure(ctx)
if err == nil {
cfg.Region = region
} else if !awsRegionPattern.MatchString(cfg.Region) {
} else if !common.AWSRegionPattern.MatchString(cfg.Region) {
return aws.Config{}, fmt.Errorf("AWS region %q is not valid and failed to get region from Infrastructure: %w", cfg.Region, err)
}

framework.Logf("AWS config loaded: region=%s", cfg.Region)
return cfg, nil
}

// getRegionFromInfrastructure reads the AWS region from the cluster's
// Infrastructure resource (status.platformStatus.aws.region).
func getRegionFromInfrastructure(ctx context.Context) (string, error) {
oc, err := common.GetOcClient(ctx)
if err != nil {
return "", fmt.Errorf("failed to create config client: %w", err)
}
infra, err := oc.Infrastructures().Get(ctx, "cluster", metav1.GetOptions{})
if err != nil {
return "", fmt.Errorf("failed to get Infrastructure: %w", err)
}
if infra.Status.PlatformStatus == nil || infra.Status.PlatformStatus.AWS == nil {
return "", fmt.Errorf("Infrastructure platformStatus.aws is nil")
}
region := infra.Status.PlatformStatus.AWS.Region
if region == "" {
return "", fmt.Errorf("Infrastructure platformStatus.aws.region is empty")
}
return region, nil
}

// createAWSClientLoadBalancer creates an AWS ELBv2 client using default credentials configured in the environment.
// It forces the public regional endpoint to avoid VPC private endpoint DNS
// resolution issues when running from a management cluster (HyperShift).
Expand Down
26 changes: 26 additions & 0 deletions openshift-tests/ccm-aws-tests/e2e/common/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,32 @@ const (
EnvSkipManagementClusterTests = "SKIP_MANAGEMENT_CLUSTER_TESTS"
)

// AWSRegionPattern matches valid AWS region names across all partitions:
// standard (us-east-1), China (cn-northwest-1), GovCloud (us-gov-west-1),
// European Sovereign Cloud (eusc-de-east-1), and ISO/ISOB (us-isob-east-1).
var AWSRegionPattern = regexp.MustCompile(`^[a-z]{2,4}(?:-[a-z0-9]+)+-\d+$`)

// GetRegionFromInfrastructure reads the AWS region from the cluster's
// Infrastructure resource (status.platformStatus.aws.region).
func GetRegionFromInfrastructure(ctx context.Context) (string, error) {
oc, err := GetOcClient(ctx)
if err != nil {
return "", fmt.Errorf("failed to create config client: %w", err)
}
infra, err := oc.Infrastructures().Get(ctx, "cluster", metav1.GetOptions{})
if err != nil {
return "", fmt.Errorf("failed to get Infrastructure: %w", err)
}
if infra.Status.PlatformStatus == nil || infra.Status.PlatformStatus.AWS == nil {
return "", fmt.Errorf("Infrastructure platformStatus.aws is nil")
}
region := infra.Status.PlatformStatus.AWS.Region
if region == "" {
return "", fmt.Errorf("Infrastructure platformStatus.aws.region is empty")
}
return region, nil
}

// GetOcClient returns an OpenShift config/v1 API client (FeatureGates, Infrastructures, etc.).
func GetOcClient(ctx context.Context) (*configv1client.ConfigV1Client, error) {
restConfig, err := framework.LoadConfig()
Expand Down
2 changes: 1 addition & 1 deletion openshift-tests/ccm-aws-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
k8s.io/api v0.36.0
k8s.io/apimachinery v0.36.0
k8s.io/client-go v0.36.0
k8s.io/cloud-provider-aws/tests/e2e v0.0.0-20260507005622-746099eda51c
k8s.io/cloud-provider-aws/tests/e2e v0.0.0-20260606003233-c34d66ed717a
k8s.io/kubernetes v1.36.0
k8s.io/pod-security-admission v0.36.0
)
Expand Down
4 changes: 2 additions & 2 deletions openshift-tests/ccm-aws-tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ k8s.io/client-go v0.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c=
k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y=
k8s.io/cloud-provider v0.36.0 h1:PtiHsId1lBJixCbl5T+gUzbgOYAPschYj8tEAxxe0Ts=
k8s.io/cloud-provider v0.36.0/go.mod h1:y/3sksoC0taJZR0PcAAYUqVyD6Jzu2X0lD4yCEPXPuI=
k8s.io/cloud-provider-aws/tests/e2e v0.0.0-20260507005622-746099eda51c h1:mXxJGVHCgE0diY1xgPg1mlmGuDhj2o8KzehT+YcOED8=
k8s.io/cloud-provider-aws/tests/e2e v0.0.0-20260507005622-746099eda51c/go.mod h1:BVLb2sMjVqNAN4t7bADRqtpdVA7brv8LcNas/kdKUJo=
k8s.io/cloud-provider-aws/tests/e2e v0.0.0-20260606003233-c34d66ed717a h1:3vIWSg8oFCQUal5G8Xj8m2hM7VrSJyqxaZkX1b6ICbM=
k8s.io/cloud-provider-aws/tests/e2e v0.0.0-20260606003233-c34d66ed717a/go.mod h1:vu0ofZopcm0LmGHdelw1LaP7oZdFZjgQ6k2fN+/MO5g=
k8s.io/component-base v0.36.0 h1:hFjEktssxiJhrK1zfybkH4kJOi8iZuF+mIDCqS5+jRo=
k8s.io/component-base v0.36.0/go.mod h1:JZvIfcNHk+uck+8LhJzhSBtydWXaZNQwX2OdL+Mnwsk=
k8s.io/component-helpers v0.36.0 h1:KznLAOD7oPxjaeheW4SOQijz9UtMO8Nvp89+lR8FYks=
Expand Down
44 changes: 27 additions & 17 deletions openshift-tests/ccm-aws-tests/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/openshift-eng/openshift-tests-extension/pkg/cmd"
e "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
Expand Down Expand Up @@ -130,26 +131,35 @@ func main() {
}
}

// getRegionFromEnv gets the region from the environment variables.
// getRegionFromEnv gets the region from environment variables, validating
// that the value looks like a real AWS region. When no valid region is
// found in the environment (e.g. HyperShift CI where LEASED_RESOURCE is
// a UUID), it falls back to the cluster's Infrastructure object.
func getRegionFromEnv() string {
region := os.Getenv("LEASED_RESOURCE")
if len(region) > 0 {
log.Debugf("Using region from LEASED_RESOURCE: %s", region)
os.Setenv("AWS_REGION", region)
return region
for _, env := range []string{"LEASED_RESOURCE", "AWS_REGION", "AWS_DEFAULT_REGION"} {
if v := os.Getenv(env); common.AWSRegionPattern.MatchString(v) {
log.Infof("Using region from %s: %s", env, v)
if err := os.Setenv("AWS_REGION", v); err != nil {
log.Warnf("Failed to set AWS_REGION from %s: %v", env, err)
return ""
}
return v
}
}
region = os.Getenv("AWS_REGION")
if len(region) > 0 {
log.Debugf("Using region from AWS_REGION: %s", region)
return region

ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
region, err := common.GetRegionFromInfrastructure(ctx)
if err != nil {
log.Warnf("Failed to get region from Infrastructure: %v", err)
return ""
}
region = os.Getenv("AWS_DEFAULT_REGION")
if len(region) > 0 {
log.Debugf("Using region from AWS_DEFAULT_REGION: %s", region)
os.Setenv("AWS_REGION", region)
return region
log.Infof("Using region from Infrastructure object: %s", region)
if err := os.Setenv("AWS_REGION", region); err != nil {
log.Warnf("Failed to set AWS_REGION from Infrastructure: %v", err)
return ""
}
return ""
return region
}

// initFrameworkForTests initializes the framework for the tests globally.
Expand All @@ -164,6 +174,7 @@ func initFrameworkForTests() error {
// 2. Build the config from the env, and set the testContext.CloudConfig (if required by the test)
// 3. Move this init to a dedicated function
testContext.Provider = "local" // TODO: OTE supports local or skeleton
testContext.KubeConfig = os.Getenv("KUBECONFIG")

// Set up AWS cloud configuration when environment variables are set.
region := getRegionFromEnv()
Expand All @@ -186,7 +197,6 @@ func initFrameworkForTests() error {
testContext.MasterOSDistro = "custom"

// Load kube client config and set the host variable for kubectl
testContext.KubeConfig = os.Getenv("KUBECONFIG")
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{
ExplicitPath: testContext.KubeConfig,
Expand Down
Loading